Почему здесь используется термин "объект" при упоминании prvalue?
Насколько я знаю, в C++17 концепция / семантика prvalue больше не является временным объектом, поэтому во многих случаях разрешение на копирование является обязательным.
Однако сегодня я наткнулся на описание обратного выражения
Если выражение является значением, объект, возвращаемый функцией, инициализируется непосредственно этим выражением. Это не требует копирования или перемещения конструктора, когда типы совпадают
Почему термин объект происходит здесь? В категории значений возврат функции, которая не является ссылочным типом, принадлежит prvalue, поэтому я думаю, что, возможно, нецелесообразно использовать термин объект.
Насколько я понимаю, prvalues больше не являются объектами, они просто ценности, я прав?
В качестве дополнения здесь также используется термин "объект".
2 ответа
Я согласен с тем, что вы говорите. На cppreference есть страница обсуждения, где вы можете высказать свои опасения. Лучший способ выразить это может быть
Если выражение является значением, результирующий объект выражения инициализируется непосредственно этим выражением.
Как вы говорите, объекты больше не возвращаются и не передаются с помощью prvalues.
В цитируемом тексте указывается, что существует объект, значение которого установлено на возвращаемое значение функции: при гарантированном исключении C++17 при возврате по значению этот объект будет чем-то похожим на переменную, создаваемую вызывающей стороной, элемент в векторе, в котором вызывающий объект также использует или push_backing, или объект, создаваемый в некоторой динамически распределенной памяти, организованной вызывающим объектом. Вы путаете это с временным, который, как вы говорите, не может быть вовлечен.
Работая систематически, вы цитируете высказывание cppreference о...
return expression;
...тот...
Если выражение является значением, объект, возвращаемый функцией, инициализируется непосредственно этим выражением. Это не требует копирования или перемещения конструктора, когда типы совпадают
Стандарт C++17 говорит в [basic.lval]:
Результатом
prvalue
это значение, которое выражение хранит в своем контексте. [...] Объект результатаprvalue
это объект, инициализированныйprvalue
;prvalue
используется для вычисления значения операнда оператора или имеет тип cvvoid
не имеет объекта результата. [ Примечание: за исключением случаев, когдаprvalue
операнд спецификатора decltype,prvalue
класса или типа массива всегда имеет объект результата. Для выброшенногоprvalue
временный объект материализован;...
Таким образом, в тексте cppreference то, что стандарт называет "объектом результата", называется "объектом, возвращаемым функцией". Язык немного неточен, говоря, что результирующий объект "возвращается", а не "инициализирован", но в целом он не вводит в заблуждение и - поскольку он избежал еще одного кусочка терминологии - может быть проще для понимания большинством читателей cppreference. Я не активно связан с сайтом, но как обычный пользователь у меня сложилось впечатление, что cppreference пытается точно объяснить суть стандарта, но упрощает язык, когда это возможно.
Хотя лежащие в основе механизмы не определены Стандартом - а практические аспекты оптимизации / ABI диктуют другую реализацию - чтобы получить представление о том, что требуется Стандарту, происходит функционально, это может помочь представить компилятор, реализующий код наподобие...
My_Object function() { return { a, b, c }; }
...
... {
My_Object my_object = function(); // caller
}
... тайно передавая адрес памяти для возвращаемого объекта функции (очень похоже на this
указатель на функции-члены)...
void function(My_Object* p_returned_object) {
new (p_returned_object) My_Object{ a, b, c };
}
Таким образом, существует объект, задействованный и созданный вызываемой функцией, но его местонахождение исключается, то есть адрес памяти, указанный вызывающим абонентом. Если результат вызова функции не используется вызывающей стороной, временный объект, по крайней мере, условно создается, а затем уничтожается.