   [C++0x] "canonical" class - copy/move construction/assignment
  Since VS2010 has some Cpp0x features implemented, I thought it was about time to start learning about them. Rvalue references will probably have the largest impact on how one should write classes. So I'm trying to find some "standard" way of implementing a class. Something that replaces "implement a non-throwing swap and implement assignment in function of copy construction". My current understanding leads to this:class Foo{private:    State m_state; //assume State to be a 'canonical' classpublic:    Foo()    {   //...   }    Foo(const Foo& other):   m_state(other.m_state)    {    }    Foo(Foo&& other):   m_state(std::forward<State>(other.m_state))    {    }    Foo& operator = (const Foo& other)    {   Foo temp(other);   *this = std::move(temp);   return *this;    }    Foo& operator = (Foo&& other)    {   m_state = std::move(other.m_state);   return *this;    }};Does that seem ok? The move constructor and move assignment are kindof doing the same thing, but any attempts to use swap to fix this have lead to infinite loops (as std::swap uses operator = (Type&&)). Is there a way to fix this?I'm also not too sure about my use of std::move and std::forward. Different texts seem to contradict each other on this issue.Any comments or links would be much appreciated.   
  Why are you using std::forward() in the move constructor? And why not write your own swap function that swaps the member data?class Foo {  private:    State m_state; //assume State to be a 'canonical' class  public:    Foo() {}    Foo(const Foo & other) : m_state(other.m_state) {}    Foo(Foo && other) : m_state(std::move(other.m_state)) {}    Foo & operator=(const Foo & other) { Foo(other).swap(*this); return *this;    }    Foo & operator=(Foo && other) { Foo(std::move(other)).swap(*this); return *this;    }    void swap(Foo & other) { using std::swap; // use ADL to lookup swap in State's namespace or swap(m_state, other.m_state); // fallback on std::swap if no such function    }};void swap(Foo & lhs, Foo & rhs) {  lhs.swap(rhs);};  As already mentioned, you should be using std::move in the move constructor and move assignment operator.  Forward is for perfect forwarding, which is a completely different concept.You need to be careful with handling assignment to self with move assignment as well as exception safety.  Not so sure I like the idea of implementing copy assignment in terms of move assignment.  It's actually causing more copies that way.Assuming a member is movable, you're copying it into temp, then moving it into *this.  If the member is not movable, you're copying it once into temp, then copying it again in the move assignment.  In either case, it would be more efficient to simply copy once and be done with it.   ;  If you don't write your own copy constructor, assignment operator and destructor, the move constructor and move assignment operator will be generated automatically. So as long as you don't use pointers as members (and you rarely should), you will be fine.   ;  Ah, I misunderstood some post I read before. It shows a templatized move constructor where the author uses std::forward instead of std::move. But that's a different case.Quote:Original post by DevFredIf you don't write your own copy constructor, assignment operator and destructor, the move constructor and move assignment operator will be generated automatically. So as long as you don't use pointers as members (and you rarely should), you will be fine.I think this is wrong... See MS Visual C++ blogQuote:Some microsoft visual studio guyAt this point, you may be wondering how this interacts with automatically generated ("implicitly declared" in Standardese) constructors and assignment operators.Move constructors and move assignment operators are never implicitly declared.The implicit declaration of a default constructor is inhibited by any user-declared constructors, including copy constructors and move constructors.The implicit declaration of a copy constructor is inhibited by a user-declared copy constructor, but not a user-declared move constructor.The implicit declaration of a copy assignment operator is inhibited by a user-declared copy assignment operator, but not a user-declared move assignment operator.So I tested it using no such user's Foo class and the following Bar classclass Bar  {  private:    Foo m_foo;  };Bar BarFactory()  {  Bar newBar;  return newBar;  }Using the BarFactory function triggers foo's copy constructor, not the move constructor. And I doubt this is a Visual Cpp bug...Thanks for all your replies!   ;Quote:Original post by KoenQuote:Original post by DevFredIf you don't write your own copy constructor, assignment operator and destructor, the move constructor and move assignment operator will be generated automatically. So as long as you don't use pointers as members (and you rarely should), you will be fine.I think this is wrong...When it comes to C++, I trust Bjarne more than MS ;-)[Edited by - DevFred on April 20, 2010 11:33:15 AM];Quote:Original post by DevFredWhen it comes to C++, I trust Bjarne more than MS ;-)I've checked with the latest standard draft, and it agrees with you :-)Quote:From the draft standard March 2010, section 12.8.10, p273If the class definition does not explicitly declare a move constructor, one will be implicitly declared as defaulted if and only if X does not have a user-declared copy constructor and the move constructor would not be implicitly defined as deleted.Bummer. I had assumed microsoft would have made the features it already implemented standard compliant.Little bit off topic, but are there other compilers that already implement this stuff properly (or any 0x stuff for that matter)? It seems gcc or intel don't implement this specific one either... ;Quote:Original post by KoenBummer. I had assumed microsoft would have made the features it already implemented standard compliant.Little bit off topic, but are there other compilers that already implement this stuff properly (or any 0x stuff for that matter)? It seems gcc or intel don't implement this specific one either...There is no "properly" since the standard isn't finished.  Also, do you realize the blog post you reference is 4 months older than the proposal to add implicit moves?  After that, it takes time to approve these things and add them in the standard.  At the time, the article was correct, but the standard changes.Microsoft's implementation in VS2010 is actually different than that post as well.  You can see some of the changes here:http://blogs.msdn.com/vcblog/archive/2010/04/06/c-0x-core-language-features-in-vc10-the-table.aspx   ;Quote:Original post by gekkoThere is no "properly" since the standard isn't finished.I understand that, but I didn't think it was still changing that much. I was under the impression that the current draft is more or less final. But apparently it will certainly not be final before 2011.I wish it was 2012 already :-)Quote:Original post by gekkoMicrosoft's implementation in VS2010 is actually different than that post as well.  You can see some of the changes hereThanks!;Quote:Original post by DevFredWhen it comes to C++, I trust Bjarne more than MS ;-)Yeah, and according to the C++ standard, you can use export with templates. You need to face reality and deal with the limitations of the tools you are using. Saying that you should write your code as if your compiler implements the language "correctly" in face of the fact that your compiler doesn't implement the language that way is just idiotic.   