Поскольку в этой ситуации у компилятора есть все необходимое для статической проверки того, что вызов act(5, 5)
не переполняется для предоставленных значений, соответствует ли стандартному поведению сбой в этом коде?
Да. Компилятору разрешено выполнять сужающее преобразование только в том случае, если он может гарантировать, что значение может быть представлено в более узком типе. Если у тебя есть
std::array<unsigned char, 2> foo = {5, 127};
тогда это будет нормально, потому что компилятор знает, что 5
и 127
можно представить. Ваш случай, однако, не то же самое. Вы выполняете свою инициализацию внутри функции, а внутри функции {aArgs...}
нет такой же гарантии, поскольку это не постоянное выражение (переменные, переданные в функцию, не являются постоянными выражениями). Из-за этого компилятор не может во всех случаях доказать, что он будет действительным, поэтому он выдает предупреждение/ошибку.
Поскольку нет суффикса литерала для получения литерала без знака char, как обойти эту ошибку || исправить этот нестандартный код?
Вы можете сделать так, чтобы ваш собственный пользователь определял литерал, чтобы создавать неподписанные символы, например
inline constexpr unsigned char operator ""_uc( unsigned long long arg ) noexcept
{
return static_cast< unsigned char >( arg );
}
//...
act(5_uc, 5_uc);
или вы можете просто передать им, как
act((unsigned char)5, (unsigned char)5);
Фактическую формулировку, которая охватывает этот случай, можно найти в [dcl.init] /7а>
Сужающее преобразование — это неявное преобразование [...]
- из целочисленного типа или типа перечисления с незаданной областью в тип с плавающей запятой, за исключением где источником является константное выражение и фактическое значение после преобразования будет соответствовать целевому типу и будет создавать исходное значение при преобразовании вернуться к исходному типу [...]
выделено мной
Как видите, для этого требуется, чтобы инициализатор был константным выражением. Поскольку параметры функции никогда не являются константными выражениями, не имеет значения, сколько статического анализа выполняет компилятор и сколько у него доказательств. Это не постоянное выражение, поэтому это невозможно сделать.
person
NathanOliver
schedule
11.10.2019
inline constexpr unsigned char operator ""_uchar( unsigned long long arg ) noexcept { return static_cast< unsigned char >( arg ); }
- person Eljay   schedule 11.10.2019static_cast<unsigned char>(args)...
. - person super   schedule 11.10.2019