【问题标题】:What are the rules about using an rvalue reference on the left side of an equals sign?在等号左侧使用右值引用的规则是什么?
【发布时间】:2019-07-02 01:12:57
【问题描述】:

所以我一直在学习右值和右值引用,并且在试验时遇到了一些代码,我无法理解其中的错误。

int&& test1(int& t)
{
    return static_cast<int&&>(t);
}

std::string&& test2(std::string& t)
{
    return static_cast<std::string&&>(t);
}


int main()
{
    int n ;
    std::string s;
    static_cast<int&&>(n) = 9;        //Error: expression must be a modifiable lvalue
    static_cast<std::string&&>(s) = "test";  //Compiles and runs fine
    test1(n) = 4;                     //Error: expression must be a modifiable lvalue
    test2(s) = "hello";               //Compiles and runs fine 
}

我只是想知道在如何处理 std::strings 和 int 的右值引用方面有什么区别,以及为什么一个有效而一个无效。

我正在使用带有 C++17 的 Visual Studio 2019

【问题讨论】:

    标签: c++ c++11 rvalue-reference lvalue-to-rvalue


    【解决方案1】:

    因为 C++ 以不同的方式处理类类型和内置类型。

    对于内置类型,不能分配右值。

    对于类类型,例如std::string, test2(h) = "hello";test2(h).operator=("hello"); 相同; operator=std::string 的成员,与其他成员函数并无特殊。如果允许在右值上调用成员 operator=,这是有效的,对于 std::string::operator= 也是如此。你甚至可以写std::string{} = "hello";之类的东西,即分配给一个很快就会被销毁的临时对象,这确实没有多大意义。

    如果要约束自定义类的成员函数只能在左值上调用,可以指定lvalue ref-qualifier (since C++11),反之亦然。例如

    struct X {
        X& operator=(const char*) & { return *this; }
        //                        ^
    };
    

    LIVE

    【讨论】:

    • 这对我来说确实有意义,谢谢。但我有一个后续问题。当我创建一个自定义类并尝试执行与以前相同的 r-value-reference 分配时,它可以工作,就像它对 std::string 所做的那样。这是因为生成了隐式移动赋值运算符吗?
    • @IsaacMorton 答案已修改。隐式生成的赋值运算符没有指定 ref 限定符,其行为与您在 std::string 中看到的相同。
    • 感谢所有帮助。尤其是 ref-qualifier,如果不是因为您的回答,就永远不会发现。确实很有帮助!
    猜你喜欢
    • 1970-01-01
    • 2020-10-06
    • 2014-01-24
    • 2021-01-21
    • 2022-12-05
    • 1970-01-01
    • 2016-04-22
    • 1970-01-01
    • 2016-10-16
    相关资源
    最近更新 更多