可能重复:
我可以列出初始化只移动类型的向量吗?
编辑1:请考虑重新投票:我的问题强调就地建设。移动构造是另一种选择,但不是这个问题的目的。感谢您的回答!
编辑 2:由于我无法回答这个问题(它已关闭),我在这里发布我自己的建议。以下内容不如我接受的答案,但可能对其他人有用。至少只有移动构造函数被调用:
std::vector<A2> vec;
{
std::array<A2,3> numbers{{{2,3},{5,6},{7,8}}};
vec.reserve(numbers.size());
for (auto &v: numbers) vec.emplace_back(std::move(v)) ;
}
原帖:
在考虑这个问题的答案时:Initialization of classes within an STL array of vectors我发现我找不到从初始化列表中就地构造向量的方法。我错过了什么?
现在想更清楚,我想要这个(完全正确的)初始化
std::vector<A2> k{{2,3},{4,5},{8,9}};
产生更类似于此的效果:
std::vector<A2> k2;
k2.reserve(3);
k2.emplace_back(2,3);
k2.emplace_back(4,5);
k2.emplace_back(8,9);
但是,在第一种情况下,在插入时临时为 A2 调用复制构造函数。有没有办法避免这种情况?标准是怎么说的?
我拼命尝试
std::vector<A2> k{{2,3},{4,5},std::move(A2{8,9})};
但这会产生对移动构造函数的额外调用,这也是我没想到的。我只是想明确暗示 A2 是临时的,我认为是暗示的。
完整示例:
#include <vector>
#include <iostream>
struct A2 {
int mk;
int mj;
A2(int k,int j) : mk(k),mj(j) {
std::cout << " constr for "<<this<< ":"<< mk<<std::endl;
}
A2(const A2& a2) {
mk=a2.mk;
mj=a2.mj;
std::cout << "copy constr for "<<this<< ":" << mk<<std::endl;
}
A2(A2&& a2) noexcept {
mk=std::move(a2.mk);
mj=std::move(a2.mj);
std::cout << "move constr for "<<this<< ":"<< mk<<std::endl;
}
};
struct Ano {
Ano() {
std::cout << " constr for "<<this <<std::endl;
}
Ano(const Ano& ano) {
std::cout << "copy constr for "<<this<<std::endl;
}
Ano(Ano&& ano) noexcept {
std::cout << "move constr for "<<this<<std::endl;
}
};
int main (){
// here both constructor and copy constructor is called:
std::vector<A2> k{{2,3},{4,5},std::move(A2{8,9})};
std::cout << "......"<<std::endl;
std::vector<A2> k2;
k2.reserve(3);
// here (naturally) only constructor is called:
k2.emplace_back(2,3);
k2.emplace_back(4,5);
k2.emplace_back(8,9);
std::cout << "......"<<std::endl;
// here only constructor is called:
std::vector<Ano> anos(3);
}
输出:
constr for 0xbf9fdf18:2
constr for 0xbf9fdf20:4
constr for 0xbf9fdf0c:8
move constr for 0xbf9fdf28:8
copy constr for 0x90ed008:2
copy constr for 0x90ed010:4
copy constr for 0x90ed018:8
......
constr for 0x90ed028:2
constr for 0x90ed030:4
constr for 0x90ed038:8
......
constr for 0x90ed048
constr for 0x90ed049
constr for 0x90ed04a