Possible Duplicate:
initializer_list and move semantics
In the following example, a copy is finally performed even if a temporary object is sended:
// test.cpp
#include <iostream>
#include <vector>
#include <utility>
#include <initializer_list>
using namespace std;
class mystr : public string
{
public:
mystr() = default;
mystr(const char* c) : string(c) { }
mystr(mystr& m) : string(m) { cout << "& " << c_str() << endl; }
mystr(mystr const & m) : string(m) { cout << "const & " << c_str() << endl; }
mystr(mystr&& m) : string(move(m)) { cout << "&& " << c_str() << endl; }
};
class myvector
{
public:
myvector(initializer_list<mystr> i)
{
cout << "Inside constructor" << endl;
v = vector<mystr>(i);
}
private:
vector<mystr> v;
};
int main()
{
mystr a("hello");
myvector v{ a, mystr("bye"), a, mystr("sorry") };
}
Output:
$ g++ --version | grep "g++"
g++ (Ubuntu/Linaro 4.7.2-2ubuntu1) 4.7.2
$ g++ -std=c++11 test.cpp
$ ./a.out
& hello
& hello
Inside constructor
const & hello
const & bye
const & hello
const & sorry
The "named" objects are copied and the temporary objects are elided, but, once the initializator list is constructed, all elements are copied other time: the initializator list has erased information of the original nature of the object. With -fno-elide-constructors
the process is better understandable:
$ g++ -std=c++11 -fno-elide-constructors test.cpp
$ ./a.out
& hello
&& hello
&& bye
&& bye
& hello
&& hello
&& sorry
&& sorry
Inside constructor
const & hello
const & bye
const & hello
const & sorry
The temporaries are moved two times, and the persistent objects are copied and moved, before arriving to the constructor, that means, in the process to create the initializator list. Once in the constructor, all objects in the list are persistents from the point of view of the constructor, and thus, they are all copied.
Is it possible to avoid this behaviour (forwarding)?
I think, a container should always move the objects (and not copy) from the initializator list to its own container, since the object are already copied one time when the initializer list is built. Why to copy two consecutive times?