繁体   English   中英

std :: vector :: emplace_back和std :: move

[英]std::vector::emplace_back and std::move

使用std::vector::emplace_backstd::move有什么好处吗? 或者它只是多余的,因为std::vector::emplace_back将进行std::vector::emplace_back -construction?

案例澄清:

std::vector<std::string> bar;

第一:

bar.emplace_back(std::move(std::string("some_string")));

第二:

std::string str("some_string");
bar.emplace_back(std::move(str));

第三:

bar.emplace_back(std::move("some_string"));

在第二个版本中,有一个优点。 当使用std::move时,调用emplace_back将调用std::string的move构造函数,这可以保存在副本上(只要该字符串不存储在SSO缓冲区中)。 请注意,在这种情况下,这与push_back基本相同。

第一个版本中的std::move是不必要的,因为字符串已经是prvalue。

std::move在第三个版本中是无关紧要的,因为无法移动字符串文字。

最简单,最有效的方法是:

bar.emplace_back("some_string");

这需要没有不必要的std::string结构,因为文字完美地转发给构造函数。

emplace_back调用了类似的东西

new (data+size) T(std::forward<Args>(args)...);

如果args是基本的 - 非rvalue引用的std::string ,则表达式将编译为

new (data+size) std::string(str); //str is lvalue - calls std::string::string(const string& rhs)

意味着复制构造函数将发生。 但是,如果你在str上使用std::move ,代码将编译为

new (data+size) std::string(str); //str is r-value reference, calls std::string::string(string&& rhs)

所以移动语义发生了。 这是一个巨大的性能提升。
注意, str是左值,它有一个名称,所以为了从它创建r值引用,你必须使用std::move

在示例中

vec.emplace_back("some literal"); 

代码将编译为

new (data+size) std::string("literal"); //calls std::string::string(const char*);

所以没有临时工。

第三个例子是胡说八道。 你不能移动文字。

emplace_back的整个想法是摆脱复制和移动操作。 您只需要将std::string输入参数传递给emplace_back 将在emplace_back方法中构造一个std::string对象。

bar.emplace_back("some_string");

如果你已经有了一个字符串,那么使用std::move是有意义的。 通过从str移动数据,将在emplace_back内构造一个std::string对象。

std::string str("some_string");
bar.emplace_back(std::move(str));

在第二种情况下,有一点是这样做的。 考虑以下代码:

int main()
{
    std::vector<std::string> bar;
    std::string str("some_string");
    bar.emplace_back(std::move(str)); str.clear();
    // bar.emplace_back(str);
    std::cout << str << std::endl;
}

如果您将注释更改为上面的行,您可以看到最终会有两个“some_string”副本(一个在bar ,一个在str )。 所以它确实改变了一些东西

否则,第一个是移动临时,第三个是移动一个常量字符串文字。 它什么都不做。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM