简体   繁体   中英

What are the rules about using an rvalue reference on the left side of an equals sign?

So I've been learning about rvalues and rvalue references and have run into some code while experimenting that I can't wrap my head around the errors of.

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 
}

I was just wondering what the differences are in how rvalue references of std::strings and ints are handled and why one works and one doesn't.

I'm using Visual Studio 2019 with C++17

Because C++ treats class types and build-in types in different ways.

For build-in types, rvalues can't be assgined.

For class types, eg std::string , test2(h) = "hello"; is just same as test2(h).operator=("hello"); ; operator= is the member of std::string , it's not special with other member functions. This is valid, if the member operator= is allowed to be called on an rvalue, and this is true for std::string::operator= . You can even write something like std::string{} = "hello"; , ie assign to a temporary which will be destroyed soon, which doesn't make much sense indeed.

If you want to constrain the member function of user-defined class can only be called on lvalues, you can specify lvalue ref-qualifier (since C++11) , or vice versa. eg

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

LIVE

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM