Nu1lPointer 2019-09-22 18:20 采纳率: 100%
浏览 615
已采纳

c++关于static_cast的问题

int &&rri = 42;
int &&rri1 = rri;

rri是一个左值,rri1不能绑定一个左值。

int&& rri1 = static_cast<int&&>(rri);

但是为什么static_cast转换后就可以了呢?static_cast转换后的类型不还是int&&的吗?

  • 写回答

1条回答 默认 最新

  • 斗酒神僧 2019-09-24 02:08
    关注
        int&& i1 = 42;                      
        //int&& i2 = i1;                                   // error, 无法将左值绑定到右值引用
        int& i3 = i1;                                        // ok
        int&& i4 = static_cast<int&&>(i1);   // ok
    

    第2行代码,编译给出类似于这样的错误信息:"无法将左值绑定到右值引用"。有一条关于右值引用的规则:编译器将命名的右值引用视为左值,未命名的右值引用视为右值。右值引用支持移动语义的实现,允许将资源从一个对象移动到另一个对象,这样可以避免代价高昂的拷贝操作,从而显著地改进程序的性能。一个命名的对象可以在程序的多个地方被引用,通过赋值或参数传递的方式。如果视一个命名的右值引用为右值,那么这个右值引可能在引用它的多个地方被移动或修改,这样必然引入不易察觉的混乱和危险。考虑下面的代码:

    #include <string>
    using namespace std;
    
    string make_string(const char* s)
    {
        return string(s);
    }
    void example()
    {
        string&& str1 = make_string("ABC");
        // str1 是 "ABC"
        string str2 = string(str1);
        // 调用拷贝构造函数string(const string&),str2 是 "ABC"
        string str3 = string(str1);
        // 调用拷贝构造函数string(const string&),str3 是 "ABC"
        string str4 = string(static_cast<string&&>(str1));
        // 调用移动构造函数string(string&&),str4 是 "ABC", str1 现在是空字符串
        string str5 = string(static_cast<string&&>(str1));
        // 调用移动构造函数string(string&&),str5 是空字符串.
    }
    

    在example函数中,编译器将str1视为左值,所以string(str1)调用拷贝构造函数,而不是移动构造函数,str2和str3分别从str1那里拷贝了资源。表达式static_cast<string&&>(str1)将str1转换为右值引用并返回,返回的右值引用是没有名字的,因此string(static_cast<string&&>(str1))调用移动构造函数,str1的资源被移动到了另一个对象,它现在变成了一个空字符串。

    有关右值引用的详细内容,请参考:https://docs.microsoft.com/en-us/cpp/cpp/rvalue-reference-declarator-amp-amp

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?