为什么 Vector<double> 接受整数元素initializer_list?

why vector<double> accepts initializer_list with integer elements?

本文关键字:元素 initializer list 整数 lt Vector double gt 为什么      更新时间:2023-10-16
#include <iostream>
#include <vector>
int main()
{
// case I: uniform initialization
//
int ii = 100;
// Error: cannot be narrowed from type 'int' to 'double' 
// in initializer list
//
double dd{ ii };
// case II: initializer_list
//
std::vector<double> vecDouble{ 1, 2.2 }; // fine!
// case III: initializer_list
//
std::vector<int> vi = { 1, 2.3 }; // error: double to int narrowing
// case IV: intializer_list
// cannot be narrowed from type 'int' to 'double'
//
std::vector<double> vecD2{ ii, 2.2 }; // Error
}

为什么caseI不接受int到double的转换,而caseI允许转换,这是不一致的。

长话短说,这是有效的,因为从常量表达式int转换为double而不是缩小转换。换句话说,这与以下代码工作的原因相同:

double x { 1 };

编译器需要构造用于大括号初始化的std::initializer_list<E>。它知道E的类型是double,因为您正在初始化std::vector<double>。C++11标准第8.5.4节对此进行了详细说明。

以下是第8.5.4.3节中的一个示例:

struct S {
S(std::initializer_list<double>); // #1
S(const std::string&); // #2
// ...
};
const S& r1 = { 1, 2, 3.0 }; // OK: invoke #1

同一节定义了缩小转换如下:

缩小转换是一种隐式转换

  • 从浮点类型转换为整数类型,或者
  • 从长double到double或float,或从double到float,除非源是常量表达式,并且转换后的实际值在可以表示的值范围内(即使无法准确表示),或
  • 从整数类型或无范围枚举类型转换为浮点类型,除非源是常量表达式,并且转换后的实际值将适合目标类型,并在转换回原始类型时产生原始值,或者
  • 从整数类型或无范围枚举类型转换为不能表示原始类型的所有值的整数类型,除非源是一个常量表达式,其值在整数提升后将适合目标类型

具有ii的两个示例属于第三类,即当源是而不是常量表达式时,从int转换为double