将 int 转换为 size_t

新手上路,请多包涵

当我将 integer 传递给 std::initializer_list< size_t > 时,我想知道 clang 编译器的以下警告:

 non-constant-expression cannot be narrowed from type 'int' to 'unsigned long' in initializer list

Why can int be casted to a size_t but an int not be passed to an std::initializer_list< size_t > , ie

 int main()
{
  size_t s_t = 0;
  int    i   = 0;

  std::initializer_list<size_t> i_l = { i };            // warning
  s_t = i;                                              // no warning

  return 0;
}

原文由 abraham_hilbert 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 2.4k
2 个回答

您与 [dcl.init.list]/7 发生冲突

缩小转换是从整数类型或无作用域枚举类型到整数类型的隐式转换[…],它不能表示原始类型的所有值,除非源是一个常量表达式,其值在整数提升后将适合进入目标类型。

由于 i 不是常量表达式,因此这算作缩小转换,并且在初始化列表中不允许缩小转换。如果你要使用

std::initializer_list<std::size_t> i_l = { 0 };

即使 0int ,它也不会缩小,因为编译器知道 0 可以在每种类型中表示。

原文由 NathanOliver 发布,翻译遵循 CC BY-SA 3.0 许可协议

来自 [dcl.init.list]:

缩小转换 是一种隐式转换 […] — 从整数类型或无作用域枚举类型到不能表示原始类型的所有值的整数类型,除非源是一个常量表达式,其值在整数提升后将适合目标类型。

我们正在从 int (允许负值)转换为 size_t (不允许),所以这是一个缩小转换。列表初始化中的缩小转换格式不正确,这就是您在这里所做的:

 std::initializer_list<size_t> i_l = { i };

但是,在其他地方缩小转换范围是可以的(就标准而言):

 s_t = i;

这就是为什么第一行格式错误而第二行格式错误的原因。

原文由 Barry 发布,翻译遵循 CC BY-SA 3.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题