为什么vector <double>接受带有整数元素的initializer_list?

时间:2017-02-11 02:32:46

标签: c++ c++11

#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进行双重转换,但caseII允许转换。

1 个答案:

答案 0 :(得分:4)

长话短说,这很有效,因为从<nav class="navbar navbar-default navbar-fixed-top"> <div style="text-align:center;"> <header style="font-size:48px;color:black;"> <a href="/">My Header</a> </header> </div> <div class="container" style="padding:0px;"> <div class="navbar-header"> <button type="button" class="navbar-toggle" data-toggle="collapse" data-target=".navbar-collapse"> <span class="sr-only">Toggle navigation</span> <span class="icon-bar"></span> <span class="icon-bar"></span> <span class="icon-bar"></span> </button> </div> <div class="navbar-collapse collapse"> <ul class="nav navbar-nav" style="text-transform:uppercase;"> <li><a href="/One">Item 1</a></li> <li><a href="/Two">Item 2</a></li> <li><a href="/Three">Item 3</a></li> </ul> </div> </div> </nav> 转换为int 不是缩小转化。换句话说,这与以下代码的工作原理相同:

double

编译器需要为大括号初始化构造double x = 1; 。它知道std::initializer_list<E>的类型为E,因为您正在初始化double。这在C ++ 11标准的8.5.4节中有详细描述。

以下是8.5.4.3节中的一个例子:

std::vector<double>

同一部分定义了缩小转换,如下所示:

  

缩小转化是隐式转化

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

struct S { S(std::initializer_list<double>); // #1 S(const std::string&); // #2 // ... }; const S& r1 = { 1, 2, 3.0 }; // OK: invoke #1 的两个示例属于第三类,即当源是常量表达式时,从ii转换为int