Why when I init std::vector with braces
std::vector<TS> vec {ts1, ts2};
Compiler call twice copy constructor operator? On the other hand - with push_back it called only once.
#include <iostream>
#include <vector>
using namespace std;
struct TS{
TS(){
cout<<"default constructor\n";
}
TS(const TS &other) {
cout<<"Copy constructor\n";
}
TS(TS &&other) noexcept{
cout<<"Move constructor\n";
}
TS& operator=(TS const& other)
{
cout<<"Copy assigment\n";
return *this;
}
TS& operator=(TS const&& other) noexcept
{
cout<<"Move assigment\n";
return *this;
}
~TS(){
cout<<"destructor\n";
}
};
int main() {
TS ts1;
TS ts2;
cout<<"-----------------------------------------\n";
std::vector<TS> vec {ts1, ts2};
//vec.push_back(ts1);
//vec = {ts1, ts2};
cout<<"-----------------------------------------\n";
return 0;
}
From what I understand,
initializer_list
s pass everything by const-reference. It is probably not safe tomove
from one. Theinitializer_list
constructor of avector
will copy each of the elements.Here are some links: initializer_list and move semantics
Is it safe to move elements of a initializer list?
Can I list-initialize a vector of move-only type?
questions regarding the design of std::initializer_list
If I understand the last part correctly, it means that two sets of copies are needed since(The previous quote is only relevant if you attempt to use aninitializer_list
does not copy the underlying elements.initializer_list
without copying out the elements.)What is the underlying structure of std::initializer_list?
If you want, you can use
emplace_back
: