新的C ++ 11 emplace方法是否使先前的C ++ 98/03 push_back / insert方法过时了?

时间:2014-04-08 13:29:31

标签: c++ performance c++11 stl

在C ++ 11中使用vector::push_back()而不是vector::emplace_back(),以及类似map::insert()而不是map::emplace()仍然有意义吗?

我的理解是新的现代C ++ 11 emplace -methods使用给定的参数(完美转发给构造函数)构造对象到位,因此它们保存了副本并且移动操作,因此它们应该比旧的C ++ 98/03对应物更有效。

我错过了什么吗?

是否可以安全地阻止使用旧式方法?

2 个答案:

答案 0 :(得分:1)

正如您所说,emplace_back意味着构建对象。那么,如果您已经拥有一个对象,并且想要在容器内复制或移动它,该怎么办?为什么要调用emplace_back来创建 new 实例,即使您可以将现有对象移动到这个新实例中呢?

对于不同的目的,两种替代方案都是有用的。 emplace_back可能与push_back具有相同的效果,但在您的代码中展示您的意图仍然更加清晰。

答案 1 :(得分:1)

根据push_back()和emplace_back()签名的不同,很容易看出push_back将与已经创建的对象一起工作(如果你在调用站点或隐式创建它,则是临时的),而emplace_back( )将使用完美转发从传递的参数构造一个对象。

void push_back( const T& value );
void push_back( T&& value );

VS

template< class... Args >
void emplace_back( Args&&... args );

代码示例

vector<int> v;
v.push_back(1); // "Constructs" an int object in place, then passes it by reference or refref
v.emplace_back(1); // Calls int constructor with argument 1 directly in place in vector


vector<SpaceShip> u;
u.push_back(SpaceShip(new Engine(), new Hull())); // Make a temporary, then COPY or MOVE
u.emplace_back(new Engine(), new Hull()); // Construct in place