Я пытаюсь сформулировать это как можно лучше, но пример — хороший способ продемонстрировать мой вопрос. Рассмотрим следующий сценарий, где переменная long a
входит в более узкий элемент массива — по существу const int b[0]
:
long a = 584;
const int b[4] = {(const int) a, 0, 0, 0};
Является ли следующий фрагмент кода эквивалентным, учитывая, что const не определен явно:
long a = 584;
const int b[4] = {(int) a, 0, 0, 0};
Оба компилируются, но стандарт определяет этот сценарий и результаты?
Кастинг в const int
производит значение типа int
, Не существует cv-квалифицированных значений типа non-class. Смотрите [expr.cast] / 1:
Результат выражения
(T)
монолитно-выражение имеет типT
, Результатом является lvalue, еслиT
является ссылкой на lvalue
тип или rvalue ссылка на тип функции и xvalue, еслиT
является rvalue ссылкой на тип объекта; иначе
результат — значение. [ Замечания: еслиT
это неклассный тип, который является cv-квалифицированным, cv-квалификаторы игнорируются, когда
определение типа полученного значения; см. 3.10. — конечная нота ]
и [basic.lval] / 4:
Класс prvalues может иметь cv-квалифицированные типы; не-классные значения всегда имеют cv-неквалифицированные типы. Если не
если не указано иное (5.2.2), значения должны всегда иметь полные типы или тип void; в дополнение к этим
типы, glvalues также могут иметь неполные типы.
Так что, даже если вы пишете актерский состав const int
полученное значение будет иметь тип int
,
Тем не менее, адвокат по языку может спросить, (int)
актерский состав и (const int)
литой гарантированно производить такое же значение. Очевидно, в вашем случае 584
вписывается в int
поэтому значение гарантированно будет 584
, В общем случае, когда long
значение может не вписываться в int
последняя точка маркера в [dcl.init] / 16 гарантирует, что результат приведения к const int
будет таким же, как приведение к int
:
… В противном случае начальное значение инициализируемого объекта является (возможно, преобразованным) значением начального
выражение tializer. Стандартные преобразования (пункт 4) будут использоваться при необходимости для преобразования инициализатора.
выражение для cv-неквалифицированная версия типа назначения;
(Все формулировки взяты из стандарта C ++ 14; акцент мой.)
Нет, const
неявно добавляется компилятором, потому что это ничего не меняет. Оба ваших фрагмента эквивалентны.
Я не думаю, что стандарт определяет этот сценарий, потому что он немного надуманный.
Ваш вопрос эквивалентен, имеет ли это значение a
является const
здесь или нет (в примере ниже). Ответ — нет, это не так, потому что вы копируете a
, Неважно, что вы не можете написать a
потому что вы только делаете чтение, а не запись.
/*const*/ int a = 10;
const int b = a;