Почему const int отлично подходит для char brace init?

Я думал, что инициализация скобки не позволяет сужение. Но почему int const разрешено для инициализации char фигурной скобки?

int value1 = 12;
char c1{value1};  // error! no narrowing

const int value2 = 12;
char c2{value2};   // why is this fine?

Посмотрите это на Godbolt.

Ответы

Ответ 1

const int value2 = 12;

value2 является константой времени компиляции. Компилятор может легко (и должен) доказать, что значение равно 12, что находится в диапазоне значений, представляемых char.

int value1 = 12;

value1 не является константой времени компиляции. Значение переменной может измениться во время выполнения.

Точная формулировка стандартного правила (цитата из последней версии, выделение добавлено):

[dcl.init.list]/7

Сужающееся преобразование - это неявное преобразование

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