Инициализация переменной constexpr

[dcl.constexpr] p10, предложение 3 гласит:

В любом объявлении переменной constexpr полное выражение инициализации должно быть постоянным выражением < / а>

Однако в этом заявлении:

constexpr int a = 10;
constexpr int b = a;

a не является постоянным выражением, поскольку это основное постоянное выражение glvalue, но не разрешенный результат постоянного выражения, поскольку он не имеет статической продолжительности хранения и не является временным объектом.

Однако с применением преобразования lvalue-to-rvalue оно станет постоянным выражением. Значит ли это, что инициализатор не обязательно должен быть постоянным выражением, а должен быть только конечный результат после преобразований?


person Krystian S    schedule 07.08.2019    source источник
comment
Отсутствие определения категории значения полного выражения кажется недостатком стандарта.   -  person xskxzr    schedule 08.08.2019


Ответы (2)


В цитированной вами ссылке см. Пункт 10:

Постоянное выражение - это либо основное постоянное выражение glvalue, которое ссылается на сущность, которая является разрешенным результатом постоянного выражения (как определено ниже), либо основное постоянное выражение prvalue, значение которого удовлетворяет следующим ограничениям:

Ваш вопрос сосредоточен на «разрешенном результате постоянного выражения» в ветке glvalue; однако в вашем примере применяется другая ветвь «выражение основной константы prvalue». Это может применяться из-за [conv.lval] / 1,

Glvalue нефункционального типа T, не являющегося массивом, может быть преобразовано в prvalue.

Я согласен, это немного сбивает с толку, что здесь под «выражением основной константы prvalue» они включают случай результата преобразования lvalue-to-rvalue для значений glvalue, которые соответствуют критериям; тогда как в некоторых других местах стандартное значение "prvalue" исключает этот случай.

person M.M    schedule 08.08.2019
comment
возможно, я неправильно понимаю, что такое полное выражение, особенно когда формулировка говорит, что преобразования являются частью полного выражения. Полное выражение - это выражение, поэтому, если преобразование является частью этого выражения, означает ли это, что внутреннее выражение эффективно вложено внутри преобразования, поэтому при оценке полного выражения вложенное выражение с примененным преобразованием является результат? - person Krystian S; 08.08.2019
comment
@KrystianS Я думаю, что часть полного выражения инициализации говорит о том, что инициализатор (после применения к нему любых преобразований) должен быть постоянным выражением - person M.M; 08.08.2019
comment
Хорошо, тогда хорошим определением для полного выражения было бы полное выражение - внешнее выражение или преобразование, которое оценивается при выполнении оператора? - person Krystian S; 08.08.2019
comment
На самом деле нет, этого не может быть, потому что полное выражение не обязательно является единственным выражением. - person Krystian S; 08.08.2019
comment
Стандарт определяет полное выражение, вы можете проконсультироваться с этим - person M.M; 08.08.2019
comment
Есть, но цель не ясна. Очевидно, он существует для определения порядка выполнения и времени жизни временных файлов, однако сбивает с толку способ его определения и использования. Утверждается, что полное выражение включает применяемые преобразования, но это сбивает с толку, потому что выражение - это нечто особенное. Кроме того, полное выражение может состоять из нескольких непересекающихся выражений, таких как элементы инициализатора, что сбивает с толку, поскольку оно описывается как единичное выражение. - person Krystian S; 08.08.2019

Слово «полное выражение» - это определенный термин. Примечательно ([intro.execution] / 5)

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

Итак, да, поскольку требование гласит: «полное выражение инициализации должно быть постоянным выражением», это означает, что для быть постоянным выражением.

person cpplearner    schedule 07.08.2019
comment
Вопрос был не в этом, а в том, что такое инициализация? Очевидно, он включает преобразования, но включает ли он инициализатор? Полное выражение инициализатора - это он сам и любые другие применяемые преобразования, но неясно, включает ли инициализация само выражение инициализатора. - person Krystian S; 07.08.2019
comment
@KrystianS Полное выражение - это как раз то, что находится в инициализаторе. - person L. F.; 07.08.2019
comment
@ L.F. Хорошо, но в примере, который я показал в вопросе, a не является постоянным выражением - person Krystian S; 07.08.2019
comment
@KrystianS a определенно является постоянным выражением. Если переменная constexpr не является постоянным выражением, что может быть? - person L. F.; 08.08.2019
comment
@ L.F. Это определенно не так, пока не будет применено преобразование lvalue-to-rvalue. - person Krystian S; 08.08.2019
comment
@KrystianS Хорошо, по общему признанию, я не пытался быть компетентным языковым юристом в предыдущем комментарии. Я хочу сказать, что вы можете ожидать, что constexpr int b = a; здесь действителен, поэтому дважды проверьте стандарт. - person L. F.; 08.08.2019
comment
@ L.F. Я думаю, что формулировка имеет смысл (однако инициализация может быть опечаткой для инициализатора), и проблема в том, как я интерпретирую полное выражение. Поскольку преобразования считаются частью полного выражения, будет ли это означать, что инициализатор эффективно вложен внутри преобразования, поэтому, когда полное выражение оценивается, его результат является результатом включающего преобразования. - person Krystian S; 08.08.2019