Допустимо ли приводить не-классное не-массивное prvalue к cv-квалифицированному типу?

Я читал на категории значений, и наткнулся на следующее (для краткости многое опущено):

Следующие выражения являются выражениями prvalue:

  • литерал (кроме строкового литерала), такой как 42, true или nullptr;

Свойства:

  • Некваливный prvalue, не являющийся массивом, не может быть квалифицирован cv.

Но … следующая программа компилируется и работает нормально на ideone.com и с g ++ 5.4.0:

#include <iostream>

int main() {
std::cout << ((const int) 42) << std::endl;
}

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

В N4296, Я нашел следующее в соответствующем отрывке:

[Выражение]

[… содержимое пропущено …]
  1. Если значение изначально имеет тип «cv T», где T представляет собой
    cv-неквалифицированный некласс, тип не массив, тип выражения
    корректируется до Т перед любым дальнейшим анализом.

Термин «изначально» это то, что бросает меня. Не ясно, разрешено ли это как результат другого выражения, такого как пользователь для явного приведения не-класса prvalue, не являющегося массивом, к cv-квалифицированному типу (который дает другое значение prvalue), или это применяется только к «root» «выражение (42 в этом случае).

У меня вопрос: разрешает ли стандарт такие выражения (который просто удаляет cv-квалификаторы), или это запрещено (и, если необходимо, где это требуется)?

4

Решение

Вы должны знать, что cppreference не является нормативным. «Cannot» может быть прочитано двумя способами:

  • Это запрещено, аля «не будет»

  • Это просто не может произойти, аля инварианты

Цитата, которую вы перечислили в тексте:

Если значение изначально имеет тип «cv T», где T представляет собой
cv-неквалифицированный некласс, тип не массив, тип выражения
корректируется до Т перед любым дальнейшим анализом.

предлагает мне, что квалифицированное CV-значение отбрасывает квалификации так же, как массивы могут распадаться на указатели (чтобы уточнить, это правило не происходит в тот момент, когда приведение будет неправильно сформировано). дефект # 1261 действительно делает язык довольно явным о том, что и где происходит.

2

Другие решения

Спасибо SanderDeDycker за указание на соответствующую часть стандарта для поиска.

На мой вопрос ответили в следующем разделе N4296 (выделение мое):

[Expr.cast]

  1. Результат выражения (T) cast-expression имеет тип T.
    результатом является lvalue, если T является ссылочным типом lvalue или rvalue
    ссылка на тип функции и значение xvalue, если T является ссылкой rvalue
    типу объекта; в противном случае результат является prvalue. [Примечание: если T является
    неклассный тип, который является cv-квалифицированным, cv-квалификаторы отбрасываются
    при определении типа полученного значения; см. пункт 5. —
    конечная нота]

Таким образом, мы можем сделать вывод, что такие выражения, как (const int) 42 совершенно легальны C ++.

2

По вопросам рекламы [email protected]