Given the following struct:
struct ABC
{
ABC(){cout << "ABC" << endl;}
~ABC() noexcept {cout << "~ABC" << endl;}
ABC(ABC const&) {cout << "copy" << endl;}
ABC(ABC&&) noexcept {cout << "move" << endl;}
ABC& operator=(ABC const&){cout << "copy=" << endl;}
ABC& operator=(ABC&&) noexcept {cout << "move=" << endl;}
};
The output of:
std::pair<std::string, ABC> myPair{{}, {}};
is:
ABC
copy
~ABC
~ABC
While the output of:
std::pair<std::string, ABC> myPair{{}, ABC{}};
is:
ABC
move
~ABC
~ABC
In attempting to understand the difference between the two I think I have identified that the first case is using copy-list-initialization, while the second one uses direct-list-initialization of an unnamed temporary (numbers 7 and 2, respectively, in here: http://ift.tt/1t18ulj).
Searching for similar questions I've found this: Why does the standard differentiate between direct-list-initialization and copy-list-initialization? and this: Does copy list initialization invoke copy ctor conceptually?.
The answers in those questions discuss the fact that for copy-list-initialization, the use of an explicit constructor would render the code ill-formed. In fact, if I make ABC's default constructor explicit, my first example won't compile but that is (perhaps) a different matter.
So, the question is: Why is the temporary copied in the first case but moved in the second? What prevents it from being moved in the case of copy-list-initialization?
As a note, the following code:
std::pair<std::string, ABC> myPair = std::make_pair<string, ABC>({}, {});
Also results in a call to ABC's move constructor (and no copy constructor call), but different mechanisms may be involved.
You can try the code out (using gcc-4.9.2 in C++14 mode) at: http://ift.tt/1GMte7F
Aucun commentaire:
Enregistrer un commentaire