我使用Visual Studio 2017版本15.3.1测试了以下代码.
v.push_back(std::move(str1))按预期工作.它将内容移动str1到矢量中.
str2是一个常量字符串.由于常量字符串在创建后无法修改,因此我希望该v.push_back(std::move(str2))语句会导致编译器警告.但令我惊讶的是,没有编译器警告.走进它后,我发现push_back(const T&)实际上已经调用了过载.该std::move中std::move(str2)似乎没有任何效果.
我的问题:是否应该在尝试移动常量对象时发出编译器警告?
// Compiled with Visual Studio 2017 version 15.3.1
std::vector<std::string> v;
std::string str1 = "string 1";
v.push_back(std::move(str1));
// Call push_back(T&&). The contents of str1 is moved into the vector.
// This is less expensive, but str1 is now valid but unspecified.
const std::string str2 = "string 2";
v.push_back(std::move(str2));
// Call push_back(const T&). A copy of str2 is added into the vector.
// str2 itself is unchanged.
Run Code Online (Sandbox Code Playgroud)
Ser*_*eyA 21
不,记住,std::move不动任何东西,它是一个美化的演员remove_reference_t.因为在你的情况下,它被铸造成const右值引用(如std::remove_reference_t<const T>为const T),它不绑定到右值引用过载push_back(T&& ),而是结合为const左值引用一个- push_back(const T& ).
有一种简单的方法可以防止静态移动来自const:只需删除它即可.
#include <type_traits>
#include <string>
//Copy this line into your global header
template<class T> void move (const T& arg) = delete; //ADL
int main()
{
{
std::string str;
std::string str2 = move(str);
}
{
//error
//const std::string str;
//std::string str2 = move(str);
}
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
840 次 |
| 最近记录: |