在 C++11 中,emplace_back()
通常优先于 push_back()
(就效率而言),因为它允许就地构造,但是将 push_back(std::move())
与已构造的对象一起使用时仍然是这种情况吗?
例如,在以下情况下,emplace_back()
仍然是首选吗?
std::string mystring("hello world");
std::vector<std::string> myvector;
myvector.emplace_back(mystring);
myvector.push_back(std::move(mystring));
// (of course assuming we don't care about using the value of mystring after)
此外,在上面的示例中,改为执行以下操作是否有任何好处:
myvector.emplace_back(std::move(mystring));
或者这里的举动完全是多余的,或者没有效果?
最佳答案
让我们看看您提供的不同调用的作用:
emplace_back(mystring)
:这是新元素的就地构造,无论您提供什么参数。由于您提供了左值,该就地构造实际上是复制构造,即这与调用push_back(mystring)
相同。push_back(std::move(mystring))
:这称为 move 插入,在std::string
的情况下是这样的。是一个就地 move 结构。emplace_back(std::move(mystring))
:这又是根据您提供的论点进行的就地构造。由于该参数是右值,因此它调用std::string
的 move 构造函数,即它是一个像 2 中那样的就地 move 结构。
换句话说,如果使用 T 类型的一个参数调用,无论是右值还是左值,emplace_back
和push_back
是等价的。
但是,对于任何其他参数,emplace_back
赢得比赛,例如 char const*
在 vector<string>
:
emplace_back("foo")
来电std::string(char const*)
用于就地施工。push_back("foo")
首先得调用std::string(char const*)
用于匹配函数签名所需的隐式转换,然后像上面的情况 2 那样进行 move 插入。因此它相当于push_back(string("foo"))
关于c++11 - 对于已构造的对象,使用 std::move 的 C++11 Push_back() 与 emplace_back() 的效率,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26860749/