使用 emplace_back 避免移动构造函数调用的最佳方法?
Best way to use emplace_back to avoid move constructor call?
我刚刚了解到 。根据该问题的答案:
When you do return T();
, this initializes the return value of the
function via a prvalue
. Since that function returns T, no temporary is
created; the initialization of the prvalue
simply directly initializes
the return value.
The thing to understand is that, since the return value is a prvalue
,
it is not an object yet. It is merely an initializer for an object,
just like T()
is.
所以我想知道,这是否适用于除以下以外的任何东西:
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构造函数,我觉得可以用来直接构造一个对象,而不是用来构造一个对象临时的,然后移动它。
除了像 g()
函数那样做的事情之外,是否有更优雅的方法来避免使用 emplace_back
调用移动构造函数?
It seems that the move constructor is still called even though a prvalue is passed directly into emplace_back
你认为你知道,但你没有将它传递给函数。你给它一个纯右值作为参数,是的,但是 emplace_back
接受的是一包 转发 references。一个引用必须引用一个对象,所以一个temporary is materialized,并移动。
正确使用emplace_back
的方法是将初始化对象的参数就地传递给它。这样你就不需要移动向量的元素类型(尽管你可能需要 move/copy 参数)。
我刚刚了解到
When you do
return T();
, this initializes the return value of the function via aprvalue
. Since that function returns T, no temporary is created; the initialization of theprvalue
simply directly initializes the return value.The thing to understand is that, since the return value is a
prvalue
, it is not an object yet. It is merely an initializer for an object, just likeT()
is.
所以我想知道,这是否适用于除以下以外的任何东西:
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构造函数,我觉得可以用来直接构造一个对象,而不是用来构造一个对象临时的,然后移动它。
除了像 g()
函数那样做的事情之外,是否有更优雅的方法来避免使用 emplace_back
调用移动构造函数?
It seems that the move constructor is still called even though a prvalue is passed directly into emplace_back
你认为你知道,但你没有将它传递给函数。你给它一个纯右值作为参数,是的,但是 emplace_back
接受的是一包 转发 references。一个引用必须引用一个对象,所以一个temporary is materialized,并移动。
正确使用emplace_back
的方法是将初始化对象的参数就地传递给它。这样你就不需要移动向量的元素类型(尽管你可能需要 move/copy 参数)。