Каковы правила использования ссылки на rvalue слева от знака равенства? - PullRequest
1 голос
/ 02 июля 2019

Итак, я изучал rvalues ​​и rvalue ссылки и наткнулся на некоторый код, экспериментируя, что я не могу обернуть голову вокруг ошибок.

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 и почему один работает, а другой нет.

Я использую Visual Studio 2019 с C ++ 17

1 Ответ

1 голос
/ 02 июля 2019

Потому что C ++ обрабатывает типы классов и встроенные типы по-разному.

Для встроенных типов нельзя определить значения.

Для типов классов, например, std::string, test2(h) = "hello"; точно так же, как test2(h).operator=("hello");;operator= является членом std::string, это не является особенным с другими функциями-членами.Это верно, если члену operator= разрешено вызываться по r-значению, и это верно для std::string::operator=.Вы даже можете написать что-то вроде std::string{} = "hello";, то есть назначить временное, которое скоро будет уничтожено, что не имеет особого смысла.

Если вы хотите ограничить функцию-член пользовательского класса, можетевызываться только для lvalue, вы можете указать lvalue ref-qualifier (начиная с C ++ 11) или наоборот.например,

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

LIVE

...