(1) g++ -v output info: Using built-in specs. COLLECT_GCC=gcc COLLECT_LTO_WRAPPER=/home/hillstone/libexec/gcc/i686-pc-linux-gnu/4.9.3/lto-wrapper Target: i686-pc-linux-gnu Configured with: ../gcc_4.9/configure --with-pkgversion='gxb'\''s c++ study' --prefix=/home/hillstone Thread model: posix gcc version 4.9.3 20141124 (prerelease) (gxb's c++ study) i build gcc by myself, Before and after gcc4.9.2 released,it has the same problem。 (2) svn info output info: Path: . URL: svn://gcc.gnu.org/svn/gcc/branches/gcc-4_9-branch Repository Root: svn://gcc.gnu.org/svn/gcc Repository UUID: 138bc75d-0d04-0410-961f-82ee72b054a4 Revision: 217996 Node Kind: directory Schedule: normal Last Changed Author: gccadmin Last Changed Rev: 217994 Last Changed Date: 2014-11-24 08:16:23 +0800 (Mon, 24 Nov 2014) (3)test code #include <iostream> #include <utility> class foo{ public: foo() = default; foo(const foo &fv):iv(fv.iv){std::cout << "foo copy constructor\n";} foo &operator=(foo &fv) { std::cout << "foo copy assignment\n"; iv = fv.iv; return *this; } ~foo() { std::cout << "foo destructor\n"; } private: int iv; }; class test { public: test() = default; test(const test &tv):iv(tv.iv){ std::cout << "test copy constructor\n"; } test &operator=(const test &fv) { std::cout << "test copy assignment\n"; iv = fv.iv; return *this; } test(test &&) = default; test &operator=(test &&) = default; private: int iv; foo fv; }; int main() { test ta; test tb(std::move(ta)); ta = std::move(tb); return 0; } (4)compiling cmmand g++ -std=c++11 test_move_operation_match.cpp -o test (5)test program output ./test foo copy constructor test copy assignment foo destructor foo destructor (6)result analysis in class test,we explicit use synthesized move operation,and define copy operation with output information。Had class test have a data member with foo class type。we make class foo have copy constructor、copy assignment operator and destructor。 there was no “test copy constructor” outputs but ”foo copy constructor“, this means that the compiler chooses the the synthesized move constructor which calls the member‘s copy constructor。Is this OK? in the ”c++ primer 5th“ 13.6.2 chapter,the class test’s move constructor should be ”delete“。similarly for move assignment operator。 Another output ”test copy assignment“,compiler uses copy assignment operator。 what about the move assignment operator? isn't synthesizeed at all or synthesized as ”delete“。 i think both the two move operations shuld be ”delete“。“=default” indicate the compiler synthesizes move operation。when compiler can't achieve,it should nofity the user by declaring “delete”。i agree with ”c++ primer“ book。 my english so poor,i may not describe the problem clearly and may have improper tone。Don't keep that in mind。
(In reply to xbguo from comment #0) > in class test,we explicit use synthesized move operation,and define copy > operation with output information。Had class test have a data member with foo > class type。we make class foo have copy constructor、copy assignment operator > and destructor。 > > there was no “test copy constructor” outputs but ”foo copy constructor“, > this means that the compiler chooses the the synthesized move constructor > which calls the member‘s copy constructor。Is this OK? The compiler behaviour looks correct to me. Let me start by pointing out that the observed behaviour is affected by a very recent core resolution of http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1402 > in the ”c++ primer 5th“ 13.6.2 chapter,the class test’s move constructor > should be ”delete“。similarly for move assignment operator。 No, it is not deleted, but there is simple no move constructor declared nor a move assignment operator (Even if it *were* deleted - but not in this example - that would just mean that these functions would be ignored during overload resolution). The move constructor of foo exist, but it just calls the base class copy constructor (selected by overload resolution), because there are no base class move constructor available. > Another output ”test copy assignment“,compiler uses copy assignment operator。 > > what about the move assignment operator? isn't synthesizeed at all or > synthesized as ”delete“。 The difference here is as follows: Again, the base class has no move constructor. But in this case the derived class also has no move assignment operator, because the base class has no copy constructor to which an rvalue could be provided as argument (since the existing copy constructor has a non-const argument). The effect is that overload resolution now cannot select test &operator=(test &&) but still finds the remaining (and matching) copy constructor test &operator=(const test &fv) > i think both the two move operations shuld be ”delete“。“=default” indicate > the compiler synthesizes move operation。when compiler can't achieve,it > should nofity the user by declaring “delete”。i agree with ”c++ primer“ book。 No, the language change has been performed intentionally to allow that copying still can happen, if a move cannot be performed. Albeit I think that the standard is clear what should happen here (and existing compilers seem to implement that correctly), I do have the feeling that the standard is currently unclear what the actual state of test &operator=(test &&) = default; is. The wording doesn't really say that it is deleted, nor does it say that it does not exist, because I cannot find the current situation exactly described. None of the cases enumerated in p23 b4 is valid here. What happens here is that overload resolution simply does not *succeed*. What the wording says it that the move assignment operator of test is not odr-used and therefore not defined, because overload resolution is not successful.
Thank you very much for your patient explanation, thanks again.