C++ 11:"使用模数缩小{}内部的转换"

m.s*_*.s. 5 c++ narrowing c++11

我尝试使用gccC++11启用以下代码编译:

unsigned int id = 100;
unsigned char array[] = { id % 3, id % 5 };
Run Code Online (Sandbox Code Playgroud)

我收到这些警告:

缩小'(id%3u)'从'unsigned int'到{}内的'unsigned char'的转换[-Wnarrowing]

看在线演示

有没有办法帮助编译器发现id%3的结果符合unsigned char

Sha*_*our 9

在这个特定的情况下,使id constconstexpr将解决问题:

constexpr unsigned int id = 100;
Run Code Online (Sandbox Code Playgroud)

因为对于具有常量表达式的情况存在例外,其转换后的结果将适合目标类型.

在更一般的情况下,您也可以使用static_cast将结果转换为unsigned char:

{ static_cast<unsigned char>( id % 3), static_cast<unsigned char>( id % 5) }
  ^^^^^^^^^^^                          ^^^^^^^^^^^
Run Code Online (Sandbox Code Playgroud)

我们可以在草案C++标准部分List-initialization中找到常量表达式和缩小转换的异常,它说:8.5.4

缩小转换是隐式转换

并包括以下子弹(强调我的):

  • 从整数类型或未范围的枚举类型到不能表示原始类型的所有值的整数类型,除非源是一个常量表达式,其整数提升后的值将适合目标类型.

注意,由于缺陷报告1449,措辞从原来的C++ 11标准草案改为我上面引用的内容.