繁体   English   中英

将int转换为size_t

[英]Converting int to a size_t

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

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

为什么int可以转换为size_tint不能传递给std::initializer_list< size_t > ,即

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;
}    

来自[dcl.init.list]:

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

我们正在将int (允许负值)转换为size_t (不允许),因此这是一个缩小的转换。 缩小转换在列表初始化中是不正确的,这是你在这里做的:

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

但是,缩小转换在其他地方也很好(就标准而言):

s_t = i;

这就是为什么第一行是格式错误但第二行不是。

你和[dcl.init.list] / 7发生了冲突

缩小转换是从整数类型或无范围枚举类型到整数类型的隐式转换,它不能表示原始类型的所有值,除非源是一个常量表达式,其积分促销后的值将适合进入目标类型。

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

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

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

当使用列表初始化来初始化对象时需要缩小转换时,程序是不正确的。

从C ++ 11标准(强调我的):

8.5.4列表初始化

...

3类型T的对象或引用的列表初始化定义如下:

...

- 否则,如果T是类类型,则考虑构造函数。 枚举适用的构造函数,并通过重载决策(13.3,13.3.1.7)选择最佳构造函数。 如果转换任何参数需要缩小转换(见下文),则程序格式错误。

指某东西的用途

int i = 0;
size_t s = {i};

属于同一条款。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM