【问题标题】:Do the new C++11 emplace methods make the previous C++98/03 push_back/insert methods obsolete? [duplicate]新的 C++11 emplace 方法是否会使以前的 C++98/03 push_back/insert 方法过时? [复制]
【发布时间】:2014-04-08 13:29:31
【问题描述】:

在 C++11 中使用 vector::push_back() 代替 vector::emplace_back() 以及类似地使用 map::insert() 代替 map::emplace() 是否仍然有意义?

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

我错过了什么吗?

不鼓励使用旧式方法是否安全?

【问题讨论】:

  • 如果您需要向后兼容?
  • emplace_back() 将调用构造函数,push_back() 将调用现有对象的复制或移动。
  • @chris:根据您链接的线程(谢谢),似乎使用vector::push_back 而不是emplace_back 的唯一原因是能够使用统一初始化。我的理解正确吗?无论如何,从性能的角度来看,emplace_back 应该更好,对吧?
  • @RedX:如果只是为了向后兼容,那他们可以不鼓励使用新代码吗?

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


【解决方案1】:

从 push_back() 和 emplace_back() 签名的差异很容易看出 push_back 将与已创建的对象一起使用(如果您在调用站点或隐式创建它,则为临时对象),而 emplace_back() 将构造一个使用完美转发从传递的参数中获取对象。

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

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

【讨论】:

  • 我会考虑比简单整数更大、更复杂的对象的差异 :)
  • 嗯,int 只是一个例子。当然,一个复杂的对象会有更多的开销并且更有趣。
【解决方案2】:

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

这两种选择都可以用于不同的目的。 emplace_back 可能能够以相同的性能与 push_back 完全相同,但在代码中显示您的意图仍然更清晰。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-07-02
    • 2016-06-29
    • 2014-02-13
    • 2013-01-25
    相关资源
    最近更新 更多