将 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_t
而 int
不能传递给 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]/7
有冲突
A narrowing conversion is an implicit conversion[...] from an integer type or unscoped enumeration type to an integer type that cannot represent all the values of the original type, except where the source is a constant expression whose value after integral promotions will fit into the target type.
由于 i
不是常量表达式,因此这算作缩小转换,并且初始化列表中不允许缩小转换。如果你要使用
std::initializer_list<std::size_t> i_l = { 0 };
那么即使 0
是一个 int
它也不会变窄,因为编译器知道 0
可以用每种类型表示。
来自[dcl.init.list]:
A narrowing conversion is an implicit conversion [...] — from an integer type or unscoped enumeration type to an integer type that cannot represent all the values of the original type, except where the source is a constant expression whose value after integral promotions will fit into the target type.
我们正在从 int
(允许负值)转换为 size_t
(不允许),因此这是一个收缩转换。缩小转换在列表初始化中格式错误,这就是你在这里所做的:
std::initializer_list<size_t> i_l = { i };
然而,缩小转换在其他地方也很好(就标准而言):
s_t = i;
这就是为什么第一行格式错误而第二行格式错误的原因。
当使用列表初始化来初始化对象时需要收缩转换时,程序格式错误。
来自 C++11 标准(强调我的):
8.5.4 List-initialization
...
3 List-initialization of an object or reference of type T is defined as follows:
...
— Otherwise, if T
is a class type, constructors are considered. The applicable constructors are enumerated and the best one is chosen through overload resolution (13.3, 13.3.1.7). If a narrowing conversion (see below) is required to convert any of the arguments, the program is ill-formed.
使用
int i = 0;
size_t s = {i};
属于同一条款。
我想知道当我将 integer
传递给 std::initializer_list< size_t >
时 clang 编译器的以下警告:
non-constant-expression cannot be narrowed from type 'int' to 'unsigned long' in initializer list
为什么 int
可以转换为 size_t
而 int
不能传递给 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]/7
有冲突A narrowing conversion is an implicit conversion[...] from an integer type or unscoped enumeration type to an integer type that cannot represent all the values of the original type, except where the source is a constant expression whose value after integral promotions will fit into the target type.
由于 i
不是常量表达式,因此这算作缩小转换,并且初始化列表中不允许缩小转换。如果你要使用
std::initializer_list<std::size_t> i_l = { 0 };
那么即使 0
是一个 int
它也不会变窄,因为编译器知道 0
可以用每种类型表示。
来自[dcl.init.list]:
A narrowing conversion is an implicit conversion [...] — from an integer type or unscoped enumeration type to an integer type that cannot represent all the values of the original type, except where the source is a constant expression whose value after integral promotions will fit into the target type.
我们正在从 int
(允许负值)转换为 size_t
(不允许),因此这是一个收缩转换。缩小转换在列表初始化中格式错误,这就是你在这里所做的:
std::initializer_list<size_t> i_l = { i };
然而,缩小转换在其他地方也很好(就标准而言):
s_t = i;
这就是为什么第一行格式错误而第二行格式错误的原因。
当使用列表初始化来初始化对象时需要收缩转换时,程序格式错误。
来自 C++11 标准(强调我的):
8.5.4 List-initialization
...
3 List-initialization of an object or reference of type T is defined as follows:
...
— Otherwise, if
T
is a class type, constructors are considered. The applicable constructors are enumerated and the best one is chosen through overload resolution (13.3, 13.3.1.7). If a narrowing conversion (see below) is required to convert any of the arguments, the program is ill-formed.
使用
int i = 0;
size_t s = {i};
属于同一条款。