对于已经构build的对象,C ++ 11的push_back()使用std :: move和emplace_back()的效率

在C ++ 11中,对于push_back()来说, emplace_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)); 

或者这里的举动完全是多余的,还是没有效果?

让我们来看看你提供的不同的呼叫:

  1. emplace_back(mystring) :这是用你提供的任何参数的新元素的就地构造。 既然你提供了一个左值,那么就地构造实际上就是一个复制构造,即和调用push_back(mystring)

  2. push_back(std::move(mystring)) :这将调用移动插入,这在std :: string的情况下是就地移动构造。

  3. emplace_back(std::move(mystring)) :这又是一个用你提供的参数进行的就地构造。 由于该参数是一个右值,因此它调用了std::string的移动构造函数,即它是一个像2中那样的就地移动构造。

换句话说,如果用Ttypes的一个参数调用,那么它是一个右值或左值, emplace_backpush_back是等价的。

但是,对于任何其他参数, emplace_back赢得比赛,例如,在一个vector<string>使用char const*

  1. emplace_back("foo")调用string::string(char const*)来就地构造。

  2. push_back("foo")首先必须调用string::string(char const*)来匹配函数的签名所需的隐式转换,然后像上面的case 2那样进行移动插入。 因此它相当于push_back(string("foo"))

emplace_back获取右值引用列表,并试图直接构build一个容器元素。 您可以使用容器元素构造器支持的所有types调用emplace_back。 当调用不是右值引用的参数emplace_back时,它会回退到普通引用,并且当参数和容器元素是相同types时,至less会调用复制构造函数。 在你的情况下,'myvector.emplace_back(mystring)'应该复制一个string,因为编译器无法知道参数myvector是可移动的。 所以插入std :: move是什么给你想要的好处。 对于已经构build的元素,push_back应该和emplace_back一样。