分配列表和初始化器列表之间 C++11 缩小的差异



C++11 给了我们初始化器列表。我了解到这些不执行缩小转换,这有时会破坏现有代码的编译,例如在对具有隐式加宽值的枚举值进行操作时:

   enum COMMAND
   {
     COMMAND_WRITE_MISC_CONFIG = 0x70
   };

   struct CommandSettings
   {
     quint8 buddy;
   };

   void NarrowingTest::testNarrowing()
   {
     quint8 i = 100;
     CommandSettings test{static_cast<quint8>(COMMAND_WRITE_MISC_CONFIG | i)};
     quint8 x = COMMAND_WRITE_MISC_CONFIG | i;
     QVERIFY(true);
   }      

如果没有强制转换,test的初始化将无法编译。

我正在寻找的是仍在工作x的赋值初始化背后的基本原理。

CommandSettings test{static_cast<quint8>(COMMAND_WRITE_MISC_CONFIG | i)};

它是一个聚合初始化。

从上面的参考资料:

聚合初始化的效果包括:

如果初始值设定项子句是表达式,则隐式转换为 根据复制初始化允许,除非它们正在缩小(如 在列表初始化中)(自 C++11 起)。


quint8 x = COMMAND_WRITE_MISC_CONFIG | i;

这是一个副本初始化。

从上面的参考资料:

副本初始化的效果包括:

否则(如果 T 和其他类型都不是类类型), 如有必要,使用标准转换来转换 其他 CV 不合格版本的 T。

它应该允许缩小转换范围,至少是为了向后兼容。

相关内容

最新更新