Почему правила возврата ссылки на перемещение, так как C ++ 23 более разрешают?C++

Программы на C++. Форум разработчиков
Ответить
Anonymous
 Почему правила возврата ссылки на перемещение, так как C ++ 23 более разрешают?

Сообщение Anonymous »

Вот mcve: < /p>
#include

int&& foo() {
int i = 2;
return i;
}

int main() {
std::cout
Это не компилируется с C ++ 11 to c ++ 20, но компилируется с GCC и Clang со времен C ++ 23 (только запускает предупреждение), и это приводит к неопределенному поведению. < /p>
Компилятор Demo < /p>
on cpprece Я обнаружил, что что -то вроде этого:

on cpprece я обнаружил, что что -то вроде:

on cpprece я обнаружил, что что -то вроде этого:

on cpprece. cppreference.com < /p>

Примечания < /h3>
Возвращение по значению может включать в себя строительство и копирование /перемещение временного объекта, если не используется Elision. Specifically, the conditions for copy/move are as follows:









Автоматический ход от локальных переменных и параметров < /strong>
Выражение-это , право на перемещение < /em>, если это (возможно, в скобках) выражение идентификатора, которое называет переменную длительность автоматического хранения, с тех пор
-неволатический тип объекта < /td>
(с тех пор C+relic> (с тех пор> (с тех пор C+relice> (с тех пор C+relic> (с тех пор C+relice> (с тех пор
no-Volatile Cobj />

- or a non-volatile rvalue reference to object type
(since C++20)


and that variable is declared
- in the body
- or as a parameter
of the внутренняя функция ограждения или выражение лямбды. < /td>
(поскольку c ++ 11) < /td>
< /tr>

Если выражение является подходящим для перемещения, разрешение на перегрузку, чтобы выбрать конструкцию для использования для инициализации возвращаемого значения или, для Co_return, для выбора, чтобы выбрать, чтобы использовать Specture. RETERE. C ++ 20) < /code> или, для CO_ERENTURN, чтобы выбрать перегрузку Orders.return_Value () выполняется дважды < /em>:
- сначала, как если бы выражение было выражением RValue (таким образом, он может выбрать конструкцию движения) и
- если бы первое разрешение перегрузки не удалось < /td>
(с тех пор. C ++ 23) < /td>
< /tr>

- или он преуспел, но не выбрал конструктор перемещения (формально, первым параметром выбранного конструктора не был ссылкой на RValue к (возможно, CV-квалифицированному) (Br /> (с тех пор CV-квалифицированного) < /td>
(с тех пор CV-квалифицированного) < /td>
(с тех пор CV-квалифицирован) < /td>
(с тех пор CV-квалифицированный) < /td>
(с тех пор CV-квалифицированный) < /td>
(с тех пор CV-квалифицированный) < /td>
(с тех пор CV-квалифицированного) C++20)


- then overload resolution is performed as usual, with expression considered as an lvalue (so it may select the copy constructor).
(since C++11)
(until C++23)


If the expression is move-eligible, it is treated as an xvalue (thus overload resolution may select the move constructor).
(since C++23)



Guaranteed copy elision
Если выражение является PRVALE, объект результата инициализируется непосредственно этим выражением. Это не включает в себя конструктор копирования или перемещения при совпадении типов (см. Elision Copy).
(так как C ++ 17)




я не смог понять эти разницы между C ++ и C. Я провел несколько экспериментов, предполагая, что это должно позволить больше оптимизации для NRVO, но эти эксперименты ничего не доказывали. < /P>
Мои вопросы: < /p>

Должна ли эта программа компилировать вообще составлен с C ++ 23? /> Каково было обоснование для введения этой разницы? Я только что нашел бумагу, которая выглядит связанной. Еще не прочитал это.>

Подробнее здесь: https://stackoverflow.com/questions/795 ... permissive
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

Вернуться в «C++»