Почему C++ 0x rvalue ссылка не значение по умолчанию?

Хорошо, я чувствую себя немного глупо, но я решил свою проблему.

Ключевой особенностью InfoPath были «Необязательные разделы», которые практически полностью решили мою проблему. Я пометил необязательные части моей формы как необязательные разделы, которые

  1. повысили ясность моей формы
  2. решили проблему вставки избыточных тегов XML в мой документ.

Я оставляю это здесь, чтобы другие заблудшие начинающие разработчики InfoPath могли использовать мое открытие.

20
задан Johannes Schaub - litb 1 October 2011 в 13:50
поделиться

2 ответа

Это было бы бессмысленно. Вы бы изменили что-то в функции, и это изменение сразу же потерялось бы, потому что это было на самом деле временным.

Причина появления нового типа связана с необходимостью решать, что на самом деле является rvalue, а что нет. Только тогда вы действительно сможете использовать их для тех классных вещей, которые они используют.

string toupper(string && s) { // for nonconst rvalues
    for(char &c : s) make_uppercase(c);
    return move(s); // move s into a returned string object
}

string toupper(string const& s) { // for the rest
    // calls the rvalue reference version, by passing 
    // an rvalue copy.
    return toupper(string(s));
}

Теперь, если у вас есть какое-то rvalue и вы передаете его в toupper, rvalue можно напрямую изменить, потому что мы знаем, что временное значение в любом случае выбрасывается, поэтому мы можем просто изменить его и не нужно копировать Это. Кроме того, то же наблюдение используется для вещей, называемых конструкторами перемещения и присваиванием перемещения. Правая часть не копируется, но ее вещи просто украдены и перенесены в * this .

Если бы вы сказали, что rvalue могут связываться с неконстантными ссылками lvalue, тогда у вас не было бы возможности выяснить, ссылается ли это на lvalue (именованный объект) или rvalue (временное) в конце.


Наверное, мало что известно, но в любом случае полезно, вы можете поместить в функцию-член lvalue или rvalue ref-квалификаторы. Вот пример, который естественным образом расширяет существующую семантику ссылок rvalue на неявный параметр объекта:

struct string {
    string& operator=(string const& other) & { /* ... */ }
};

Теперь вы больше не можете сказать

string() = "hello";

Что сбивает с толку и большую часть времени не имеет смысла. & выше говорит о том, что оператор присваивания может быть вызван только для lvalue. То же самое можно сделать для rvalues, поместив && .

тогда у вас не будет возможности выяснить, ссылается ли это на lvalue (именованный объект) или rvalue (временное) в конце.


Наверное, мало что известно, но в любом случае полезно, вы можете поместить в функцию-член lvalue или rvalue ref-квалификаторы. Вот пример, который естественным образом расширяет существующую семантику ссылок rvalue на неявный параметр объекта:

struct string {
    string& operator=(string const& other) & { /* ... */ }
};

Теперь вы больше не можете сказать

string() = "hello";

Что сбивает с толку и большую часть времени не имеет смысла. & выше говорит о том, что оператор присваивания может быть вызван только для lvalue. То же самое можно сделать для rvalues, поместив && .

тогда у вас не будет возможности выяснить, ссылается ли это на lvalue (именованный объект) или rvalue (временное) в конце.


Наверное, мало что известно, но в любом случае полезно, вы можете поместить в функцию-член lvalue или rvalue ref-квалификаторы. Вот пример, который естественным образом расширяет существующую семантику ссылок rvalue на неявный параметр объекта:

struct string {
    string& operator=(string const& other) & { /* ... */ }
};

Теперь вы больше не можете сказать

string() = "hello";

Что сбивает с толку и большую часть времени не имеет смысла. & выше говорит о том, что оператор присваивания может быть вызван только для lvalue. То же самое можно сделать для rvalues, поместив && .

Вот пример, который естественным образом расширяет существующую семантику ссылок rvalue на неявный параметр объекта:

struct string {
    string& operator=(string const& other) & { /* ... */ }
};

Теперь вы больше не можете сказать

string() = "hello";

Что сбивает с толку и большую часть времени не имеет смысла. & выше говорит о том, что оператор присваивания может быть вызван только для lvalue. То же самое можно сделать для rvalues, поместив && .

Вот пример, который естественным образом расширяет существующую семантику ссылок rvalue на неявный параметр объекта:

struct string {
    string& operator=(string const& other) & { /* ... */ }
};

Теперь вы больше не можете сказать

string() = "hello";

Что сбивает с толку и большую часть времени не имеет смысла. & выше говорит о том, что оператор присваивания может быть вызван только для lvalue. То же самое можно сделать для rvalues, поместив && .

43
ответ дан 29 November 2019 в 23:04
поделиться

Поскольку добавление нового типа ссылки позволяет вам написать две перегрузки метода:

void CopyFrom(MyClass &&c)
{
    dataMember.swap(c);
}

void CopyFrom(const MyClass &c)
{
    dataMember.copyTheHardWay(c);
}

Версия, которая принимает новый вид ссылки, может изменять переменную, которую она получает, потому что это переменная больше нигде не будет использоваться. Таким образом, он может «украсть» его содержимое.

Это единственная причина, по которой эта функция была добавлена; сохранение одного типа ссылки не приведет к желаемой цели.

12
ответ дан 29 November 2019 в 23:04
поделиться
Другие вопросы по тегам:

Похожие вопросы: