static_cast 到右值引用和 std::move 在初始化中更改它们的参数

static_cast to r-value references and std::move change their argument in an initialization

下面的简单代码显示 static_cast 为 r 值引用类型和 std::move 可能会更改它们的输入参数(此处为变量 inupt)初始化语句取决于被初始化的对象的类型。有人可以解释这种行为吗?

我至少很高兴 static_cast 和 std::move 的行为相似,因为 std::move 确实在幕后使用了 static_cast

#include <iostream>
#include <string>

int main() {

   {
      std::string input("hello");
      std::string&& result = static_cast<std::string&&>(input);
      std::cout << "cast case 1: input: " << input << " result: " << result << std::endl; // prints: cast case 1: input: hello result: hello
   } 

   {
      std::string input("hello");
      std::string result = static_cast<std::string&&>(input);
      std::cout << "cast case 2: input: " << input << " result: " << result << std::endl; // prints: cast case 2: input:  result: hello
   }

   {
      std::string input("hello");
      static_cast<std::string&&>(input);
      std::cout << "cast case 3: input: " << input << std::endl; // prints: cast case 3: input: hello
   }

   {
      std::string input("hello");
      std::string&& result = std::move(input);
      std::cout << "move case 1: input: " << input << " result: " << result << std::endl; 
      // prints: move case 1: input: hello result: hello
   } 

   {
      std::string input("hello");
      std::string result = std::move(input);
      std::cout << "move case 2: input: " << input << " result: " << result << std::endl; 
      // prints: move case 2: input:  result: hello
   }

   {
      std::string input("hello");
      std::move(input);
      std::cout << "move case 3: input: " << input << std::endl; 
      // prints: move case 3: input: hello
   }

}

您观察到的行为不足为奇且合情合理。

当你使用

  std::string result = static_cast<std::string&&>(input);

调用移动构造函数初始化result。移动构造函数将 移动 input 的内容到 result.

是有道理的

对比

  std::string&& result = static_cast<std::string&&>(input);

这里,result不是新对象。它只是 input 的 r 值引用。这里没有任何内容需要移动 input 的内容。

at least static_cast and std::move behave similarly since std::move does use static_cast

不仅相似,而且做的事情完全一样。 std::move 是对右值引用的静态转换。

Can someone explain this behavior?

  1. result 是引用 input。绑定引用不会修改引用的对象。
  2. 一个对象被初始化。由于它是从右值初始化的,因此使用了移动构造函数。根据 std::string 的文档,input 对象处于未指定但有效的状态,该状态可能与移动前的状态不同。
  3. 转换结果被丢弃。这没有副作用,input不会被修改。