此处 和 此处 存在类似的问题,但我认为我们还没有明确的答案,然后我重新提出了问题。
C++11 标准有两种在向量末尾添加新元素的方法,它们是 std::vector::push_back
和 std::vector::emplace_back
。
它们之间的区别在于 std::vector::emplace_back
构造对象,而 std::vector::push_back
基本上是复制对象(或原始类型)或将其移动到向量的末尾。
然后 std::vector::push_back
看起来将原始类型添加到 std::vector
中的更好选择。例如:
std::vector<int> vVec;
vVec.push_back(10);
int iVar 30;
vVec.push_back(iVar);
但是当我们谈论对象时,我并不太清楚。让我们以 std::string 的向量为例。如果我想添加一个文字字符串,我将使用 std::vector::emplace_back
而当我想复制或移动一个字符串对象时,我将使用 std::vector::push_back
?
为了更清楚我在问什么,让我们看几个场景:
第一种情况:
std::vector<string> vVec;
std::string sTest("1st scenario");
vVec.push_back(sTest);
vVec.emplace_back(sTest);
Push_back make a copy of sTest
and associate to the new element in the end of vVec
meanwhile emplace_back
create the string object in the end of vVec
并将 sTest
的内容复制到其中。在这种情况下哪个更有效或无关紧要?
第二种情况:
std::vector<string> vVec;
std::string sTest1("2st scenario");
std::string sTest2("2st scenario");
vVec.push_back(move(sTest1));
vVec.emplace_back(move(sTest2));
Push_back 已准备好移动语义,但是 emplace_back
会发生什么?在这种情况下,哪个更有效?
第三种情况:
std::vector<string> vVec;
std::string sTest("3st scenario");
vVec.push_back(sTest.substr(4,4));
vVec.emplace_back(sTest.substr(4,4));
因为 std::string::substr 返回另一个 std::string 我们有与第二种情况相同的情况?
结论
如果 std::vector::emplace_back
比 std::vector::push_back
仅在涉及文字(就地构造)时更有效,那么使用它真的合理吗?如果有,你能给我举一些例子吗?
重要的是要注意 std::vector::emplace_back
是在 c++11 中而不是在 c++0x 中实现的,那么我认为它有充分的理由存在。
原文由 TheArchitect 发布,翻译遵循 CC BY-SA 4.0 许可协议
我需要一段时间才能真正理解 aschepler 所说的使用 std::vector::emplace 的优势。
我发现更好的使用场景是当我们有自己的类在构造时接收一些数据。
为了更清楚,让我们假设我们有:
然后我们可以有这样的一行:
然后std::vector::emplace 将比std::vector::push_back 更有效地就地构造MyObject。