
2014-02-15 14:11 GMT+01:00 Adam Wulkiewicz
Hi,
Krzysztof Czainski wrote:
2014-02-15 1:13 GMT+01:00 Adam Wulkiewicz
: b) here I have a copy as well, probably because Matrix has a non-static
data member without a move assignment operator and that is is not trivially copyable c = boost::move(b); after declaring "proper" move assignment in the member class (instead of copy and swap) or using copy and swap + move ctor in Matrix everything works as expected.
Do you get a copy in C++11 here? I get a move() in C++11, and a copy in C++98. And that's what I expect, because C++11 auto-generates copy- and move-assignment operators, and both use the pass-by-value assignment of CopyMoveDemo correctly.
Yes, in GCC4.7, Clang3.2, MinGW 4.7, VS2010, VS2013.
However VS isn't good for testing the standard. For instance it doesn't implicitly delete the copy ctor if move ctor is defined and therefore permits copying.
Assuming that my understanding is correct, with copy and swap the move
assignment operator can't be implicitly declared.
Why?
I'll leave the interpretation of the standard to smarter than me but according to this: http://en.cppreference.com/w/cpp/language/move_operator
<cite> The implicitly-declared or defaulted move assignment operator for class |T| is defined as /deleted/ in any of the following is true: ... |- T| has a non-static data member or a direct or virtual base without a move assignment operator that is not trivially copyable. </cite>
Our member isn't trivially copyable and hasn't declared move assignment, because our assignment takes parameter by value not by && so it's not move assignment. Well, not the explicitly defined one, according to the same page:
<cite> A move assignment operator of class |T| is a non-template non-static member function with the name operator= that takes exactly one parameter of type T&&, const T&&, volatile T&&, or const volatile T&&. </cite>
Btw, according to page: http://en.cppreference.com/w/ cpp/language/as_operator
<cite> A copy assignment operator of class |T| is a non-template non-static member function with the name operator= that takes exactly one parameter of type T, T&, const T&, volatile T&, or const volatile T& </cite>
so our assignment operator is copy assignment.
Hmm, it's a pity IMHO, but I agree. So if class X has a base or member Y with an assignment operator taking Y by value, it implies X's auto-generated move assignment is declared deleted. Can anyone please confirm these requirements with the standard?
So is there an implicitly declared move assignment in the member class? According to the first mentioned page:
<cite> If no user-defined move assignment operators are provided for a class type (struct, class, or union), and all of the following is true:
* there are no user-declared copy constructors * there are no user-declared move constructors * there are no user-declared copy assignment operators * there are no user-declared destructors * the implicitly-declared move assignment operator would not be defined as deleted
</cite>
AFAIU only the last point is true.
So this is my reasoning. I'd say that there is a bug in GCC4.8, but maybe it's a feature ;)
Btw, in the same time std::is_move_assignable<Matrix>::value == true (MinGW 4.7)
Interesting, thanks for your input, Adam. Regards, Kris