Hum*_*awi 20 c++ vector move-semantics c++11
使用std::vector::emplace_back和std::move一起有什么好处?或者它只是多余的,因为std::vector::emplace_back会做一个inplace-construction?
案例澄清:
std::vector<std::string> bar;
Run Code Online (Sandbox Code Playgroud)
第一:
bar.emplace_back(std::move(std::string("some_string")));
Run Code Online (Sandbox Code Playgroud)
第二:
std::string str("some_string");
bar.emplace_back(std::move(str));
Run Code Online (Sandbox Code Playgroud)
第三:
bar.emplace_back(std::move("some_string"));
Run Code Online (Sandbox Code Playgroud)
Tar*_*ama 22
在第二个版本中,有一个优点.调用emplace_back将调用std::stringwhen std::move的使用时的移动构造函数,这可以保存在副本上(只要该字符串不存储在SSO缓冲区中).请注意,这与push_back本例中的基本相同.
std::move 在第一个版本中是不必要的,因为字符串已经是prvalue.
std::move 在第三个版本是无关紧要的,因为字符串文字无法移动.
最简单,最有效的方法是:
bar.emplace_back("some_string");
Run Code Online (Sandbox Code Playgroud)
这需要没有不必要的std::string构造,因为文字完美地转发给构造函数.
emplace_back 打电话给某事
new (data+size) T(std::forward<Args>(args)...);
Run Code Online (Sandbox Code Playgroud)
如果args是basic - 非rvalue-referenced std::string,表达式将编译为
new (data+size) std::string(str); //str is lvalue - calls std::string::string(const string& rhs)
Run Code Online (Sandbox Code Playgroud)
意味着复制构造函数将发生.但是,如果你使用std::moveon str,代码将编译为
new (data+size) std::string(str); //str is r-value reference, calls std::string::string(string&& rhs)
Run Code Online (Sandbox Code Playgroud)
所以移动语义发生了.这是一个巨大的性能提升.
注意,这str是左值,它有一个名称,所以为了从它创建r值引用,你必须使用std::move.
在示例中
vec.emplace_back("some literal");
Run Code Online (Sandbox Code Playgroud)
代码将编译为
new (data+size) std::string("literal"); //calls std::string::string(const char*);
Run Code Online (Sandbox Code Playgroud)
所以没有临时工.
第三个例子是胡说八道.你不能移动文字.
整个想法emplace_back是摆脱复制和移动操作。您只需要传递std::stringinto 的输入参数emplace_back。std::string将在emplace_back方法内部构造一个对象。
bar.emplace_back("some_string");
Run Code Online (Sandbox Code Playgroud)
如果您已经有一个字符串,那么使用std::move. std::string将emplace_back通过从 移动数据在内部构造一个对象str。
std::string str("some_string");
bar.emplace_back(std::move(str));
Run Code Online (Sandbox Code Playgroud)