Forums before death by AOL, social media and spammers... "We can't have nice things"
|    comp.lang.c++.moderated    |    Moderated discussion of C++ superhackery    |    33,346 messages    |
[   << oldest   |   < older   |   list   |   newer >   |   newest >>   ]
|    Message 33,287 of 33,346    |
|    =?ISO-8859-2?Q?Krzysztof_Czai=F1ski to All    |
|    Re: auto-generated move assignment and b    |
|    26 Feb 14 05:42:14    |
   
   From: 1czajnik@googlemail.com   
      
   On Monday, February 24, 2014 10:38:12 PM UTC+1, Daniel Krügler wrote:   
   > Am 24.02.2014 15:23, schrieb Krzysztof Czainski:   
   >   
   > > On Monday, February 17, 2014 9:35:29 PM UTC+1, Daniel Krugler wrote:   
   >   
   > >> Krzysztof Czainski:   
   > >>> So the standard treats A's assignment operator taking A by value as   
   > >>> copy-assignment.   
   > >>   
   > >> Yes, this needs to be the case, because a operator= overload of the   
   form   
   > >>   
   > >> T& T::operator=(T)   
   > >>   
   > >> was already a copy-assignment operator in previous versions of C++.   
      
   But there were no move assignment operators, nor move constructors in   
   previous C++.   
      
   [...]   
      
   > > I intend it to be a universal assignment operator. Typically:   
   >   
   > > T() = default;   
   > > T( T const& ) = default;   
   > > T( T&& ) = default;   
   > > T& T::operator=( T x ) { swap(*this,x); return *this; }   
   >   
   > > Here, I see T& T::operator=( T ) as a replacement for:   
   > > T& T::operator=( T const& )   
   > > T& T::operator=( T&& )   
   >   
   > > Notice, that the following sets of overloads are ambiguous:   
   >   
   > > T& T::operator=( T )   
   > > T& T::operator=( T&& )   
   >   
   > > or   
   >   
   > > T& T::operator=( T const& )   
   > > T& T::operator=( T )   
   >   
   > > Therefore I believe   
   >   
   > > T& T::operator=( T )   
   >   
   > > is both the copy and move assignment operator.   
   >   
   > Sure, it is possible to consider it conceptually this way, but   
   > technically it is a copy assignment operator (as it had been in C++03)   
   > and this difference becomes obvious, if you consider the effects on   
   > "container" types - that is types, that either contain T as non-static   
   > data member or as a direct base class: Because T& T::operator=(T)   
   > declares a copy-assignment operator, the corresponding "container" type   
   > will (implicitly) always declare a copy-assignment operator as well.   
      
   Yes, so with T& T::operator=( T ) I think both: copy and move asignments   
   in "container" classes should be generated. And with the fix by CWG 1402   
   they will be.   
      
   > > But then, calling:   
   > > T& T::operator=( T )   
   > > "copy assignment" is misleading to me, because it seems no more a copy   
   > > assignment than a move assignment.   
   >   
   > I would argue that describing this function as copy assignment character   
   > of T makes sense, because you can apply an lvalue of T as argument, but   
   > for any move-assignment operator this would not be possible. And if the   
   > argument is an lvalue, this function will never modify it, so it truly   
   > is non-mutating for lvalues. But I understand the point that you are   
   > trying to make: For non-constant rvalues this function behaves   
   > potentially mutating and has therefore some aspects of a typical move   
   > operation.   
   >   
   > HTH & Greetings from Bremen,   
   > - Daniel Krügler   
      
   Thank you for explaining this, Daniel, but this did not convince me.   
   I will try to support my statement, that calling T& T::operator=( T ) is   
   misleading. Consider these classes:   
      
   struct A // noncopyable   
   {   
    A() = default;   
    A( A const& ) = delete;   
    A( A&& ) = delete; // this is redundant, here, isn't it?   
    A& operator=( A ) {}   
   };   
      
   An object of type A can't be copy assigned to or move assigned to,   
   and yet in the same time it has a public "copy assignment operator".   
   Come on, in practice A isn't copy assignable, nor move assignable!   
      
   struct B // movable only   
   {   
    B() = default;   
    B( B const& ) = delete;   
    B( B&& ) = default;   
    B& operator=( B ) {}   
   };   
      
   An object of type B can't be copy assigned to, but can be move assigned to,   
   and yet in the same time it has a public "copy assignment operator".   
   Come on, in practice B isn't copy assignable, but it is move assignable!   
      
   struct C // copyable only   
   {   
    C() = default;   
    C( C const& ) = default;   
    // C( C&& ) not declared, so that the copy ctor is used instead   
    C& operator=( C ) {}   
   };   
      
   An object of type C can be copy assigned to and move assigned to,   
   and both will do the same -- copy. This is the case, where it in deed   
   it has a copy assignment operator.   
      
   struct D // copyable and movable   
   {   
    D() = default;   
    D( D const& ) = default;   
    D( C&& ) = default;   
    D& operator=( D ) {}   
   };   
      
   An object of type D can be copy assigned to and truly move assigned to.   
   I mean truly move assigned, no copy occurs. But it has a public   
   "copy assignment operator". Come on, in practice D is both copy assignable   
   and move assignable.   
      
   I wonder, what should the traits is_copy_assignable and is_move_assignable   
   report for the above four classes?   
      
   As shown above, a class that has a "copy assignment operator" in practice   
   behaves like it had other set of assignment operators (except for class C).   
   I call that misleading. I think it should be clearly stated, that   
   any class that has T& operator=( T ) has:   
   - a copy assignment operator iff it is copy constructable, and   
   - a move assignment operator iff it is move constructable.   
   (iff == if and only if)   
      
   I hope this shows my concern better.   
      
   Regards,   
   Kris   
      
      
   --   
    [ See http://www.gotw.ca/resources/clcm.htm for info about ]   
    [ comp.lang.c++.moderated. First time posters: Do this! ]   
      
   --- SoupGate-Win32 v1.05   
    * Origin: you cannot sedate... all the things you hate (1:229/2)   
|
[   << oldest   |   < older   |   list   |   newer >   |   newest >>   ]
(c) 1994, bbs@darkrealms.ca