在C++11中,emplace_back()
通常比push_back()
更受欢迎(就效率而言),因为它允许就地构造,但是当将与已经构造的对象一起使用时,是否仍然是这种情况?
例如,在下面这样的情况下,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));
或者,这里的迁移是完全多余的,还是没有任何影响?
发布于 2014-11-11 17:27:06
让我们看看您提供的不同调用有什么作用:
emplace_back(mystring)
:这是新元素的就地构造,使用您提供的任何参数。由于您提供了一个左值,因此该就地构造实际上是一个复制构造,即这与调用push_back(mystring)
相同
这称为移动插入,在std::string
的情况下是一个就地move-construction.
emplace_back(std::move(mystring))
:这又是一个使用您提供的参数的就地构造。由于该参数是一个右值,因此它调用std::string
的移动构造函数,即它是一个原地移动构造,如2.换句话说,如果用一个T类型的参数调用,无论是右值还是左值,emplace_back
和push_back
都是等价的。
但是,对于任何其他参数,emplace_back
将赢得竞争,例如,在vector<string>
中使用char const*
emplace_back("foo")
为in-place-construction.调用std::string(char const*)
push_back("foo")
首先必须调用std::string(char const*)
进行匹配函数签名所需的隐式转换,然后调用移动插入,如上例2所示。因此,它等同于push_back(string("foo"))
发布于 2014-11-11 17:55:00
emplace_back获取一个右值引用列表,并尝试直接在适当的位置构造一个容器元素。您可以使用容器元素构造函数支持的所有类型调用emplace_back。当为不是右值引用的参数调用emplace_back时,当参数和容器元素属于同一类型时,它将“后退”到正常引用,并且至少会调用复制构造函数列表。在你的例子中,'myvector.emplace_back(mystring)‘应该复制字符串,因为编译器无法知道参数myvector是可移动的。因此,插入std::move,让您获得所需的好处。对于已经构造的元素,push_back应该和emplace_back一样工作。
https://stackoverflow.com/questions/26860749
复制相似问题