0

我的问题包含两个部分:

  1. 功能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
    
  2. 为什么这样的代码:

    std::string s1 = "123";
    std::string s2 = std::move(s1);
    std::cout << s1 << std::endl;  //empty
    std::cout << s2 << std::endl;  //123
    

    其中std::move()仅使用 astatic_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空字符串?

我猜,这是因为使用了string after的move 构造函数s2 =。它必须通过等于nullptr或 0 字符串对象中的所有数据来擦除初始字符串。虽然std::move()它本身只返回右值。这是正确的吗?

我知道我的问题是static_cast 到 r-value 引用和 std::move 在初始化中更改其参数的重复,但我还没有找到明确的解释。

4

2 回答 2

0

在阅读您的问题时,我有一种感觉,您已经了解正在发生的事情并希望得到确认

我猜,这是因为使用了stringafter s2 = 的 move 构造函数。它必须通过等于nullptr或 0string对象中的所有数据来擦除初始字符串。虽然std::move()它本身只返回右值。

这是正确的吗?

是的,你没看错。这基本上就是正在发生的事情。

std::move不会移动,也不会“自行”改变对象的任何状态。它只是将给定对象的类型转换为右值引用。

它是一个在您的示例std::basic_string中消除的构造函数。s1

cppreference中,它简要介绍了它的作用:

. ..使用移动语义构造带有其他内容的字符串。other处于有效但未指定的状态。

尝试编写这样的示例代码来证明您的观点:

std::string s = "Hello World";
(void)std::move(s); // (void) is there to discard the warning message.
std::cout << s;

你可以看到s根本没有改变。

于 2021-08-01T16:08:10.027 回答
0
template<typename Tp>
constexpr typename 
std::remove_reference<Tp>::type&&
move(Tp&& _t) noexcept
{ return static_cast<typename std::remove_reference<Tp>::type&&>(_t); }

std::move()返回对右值实体的新引用(右值引用),即使初始实体是左值。它是通过使用通用引用Tp&&作为可以引用左值或右值表达式的输入参数,从实体中删除所有引用的 type_traits 函数,并通过在末尾std::remove_reference添加 && 将其转换为右值引用来实现的。static_cast

任何引用只是它所引用的实体的另一个名称,我们可以通过这个引用来改变那个实体。在某些近似中,引用被作为它所引用的对象来处理。

因此,std::move()返回一个对右值实体的新引用,并且根据列出的上层推理,这个右值引用被认为是一个右值实体。因此 std::move() 的结果可能会作为右值参数输入到适当的构造函数或函数中。因此,为了改变它所引用的实体的引用能力,我们可以改变初始实体,即使它是一个左值(设置为零 ptr 等)

于 2021-11-24T11:31:38.097 回答