我刚刚了解了guaranteed copy elision in C++17。根据对该问题的回答:
所以我想知道,此功能除以下用途外是否有用:
T f() {return T();}
T t = f();
因此,我使用
emplace_back
编写了此代码以对其进行测试:#include <vector>
#include <iostream>
struct BigObj{
BigObj() = default;
BigObj(int) { std::cout << "int ctor called" << std::endl; }
BigObj(const BigObj&){
std::cout << "copy ctor called" << std::endl;
}
BigObj(BigObj&&){
std::cout << "move ctor called" << std::endl;
}
};
BigObj f(){ return BigObj(2); }
int g(){ return 2; }
int main(){
std::vector<BigObj> v;
v.reserve(10);
std::cout << "emplace_back with rvalue \n";
v.emplace_back(1+1);
std::cout << "emplace_back with f()\n";
v.emplace_back(f());
std::cout << "emplace_back with g()\n";
v.emplace_back(g());
}
这是我得到的输出(禁用复制省略):
emplace_back with rvalue
int ctor called
emplace_back with f()
int ctor called
move ctor called
emplace_back with g()
int ctor called
即使
prvalue
直接传递到emplace_back
,似乎仍会调用move构造函数,我认为这可以用于直接构造对象,而不是用于构造临时对象然后移动它。除了执行类似
emplace_back
函数的操作之外,还有没有其他更优雅的方法来避免使用g()
调用move构造函数? 最佳答案
您以为可以,但是不会将其传递给函数。您给它一个prvalue作为参数,是的,但是emplace_back
接受的是一包转发引用的包。引用必须引用一个对象,即temporary is materialized,并已移动。
使用emplace_back
的正确方法是向其传递用于初始化对象的参数。这样,您无需移动 vector 的元素类型(尽管您可能需要移动/复制参数)。