【发布时间】:2018-09-19 19:28:12
【问题描述】:
我刚刚了解了guaranteed copy elision in C++17。根据该问题的答案:
当您执行
return T();时,这会初始化 通过prvalue运行。由于该函数返回 T,因此没有临时 创建;prvalue的初始化只是直接初始化 返回值。要理解的是,由于返回值是
prvalue, 它还不是一个对象。它只是一个对象的初始化器, 就像T()一样。
所以我想知道,这是否适用于:
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,我认为它可以用来直接构造一个对象,而不是用来构造一个临时的然后移动它。
除了执行g() 函数所做的事情之外,还有更优雅的方法来避免使用emplace_back 调用移动构造函数吗?
【问题讨论】: