问题描述
我的问题包含两部分:
-
函数
static_cast<Т>(arg)
会改变arg
的内部吗?显然不是,根据这样的代码:float i1 = 11.5; int x = static_cast<int>(i1); std::cout << i1<<std::endl; //11.5 std::cout << x<<std::endl; //11
-
为什么会有这样的代码:
std::string s1 = "123"; std::string s2 = std::move(s1); std::cout << s1 << std::endl; //empty std::cout << s2 << std::endl; //123
其中
std::move()
仅使用static_cast
到 r 值:template<typename _Tp> constexpr typename std::remove_reference<_Tp>::type&& move(_Tp&& __t) noexcept { return static_cast<typename std::remove_reference<_Tp>::type&&>(__t); }
使
s1
为空字符串?
我猜,是因为在s2 =
之后使用了字符串的移动构造函数。它必须通过将字符串对象中的所有数据等于 nullptr
或 0 来擦除初始字符串。而 std::move()
本身仅返回右值。正确吗?
我知道我的问题与 static_cast to r-value references and std::move change their argument in an initialization 类似,但我没有找到明确的解释。
解决方法
在阅读您的问题时,我有一种感觉,您已经了解正在发生的事情,但仍希望确认。
我猜,这是因为在 s2 = 之后使用了 string
的移动构造函数。它必须通过等于 nullptr
或 0 string
对象中的所有数据来擦除初始字符串。而 std::move()
本身仅返回右值。
正确吗?
是的,你没看错。基本上就是这样。
std::move
不会移动并且不会改变对象“自身”的任何状态。
它只是将给定对象的类型转换为右值引用。
它是 std::basic_string
的构造函数,它消除了示例中的 s1
。
在 cppreference 中,它为您简要介绍了它的作用:
... 使用移动语义构造具有 other 内容的字符串。 other
处于有效但未指定的状态。
尝试编写这样的示例代码来证明您的观点:
std::string s = "Hello World";
(void)std::move(s); // (void) is there to discard the warning message.
std::cout << s;
您可以看到 s
完全没有改变。