std::initializer_list不允许缩小

std::initializer_list does not allow narrowing

本文关键字:不允许 缩小 list initializer std      更新时间:2023-10-16

我有这个Vector类,但它给出了错误。

narrowing conversion of ‘lst.std::initializer_list<_E>::size [with _E = double, std::initializer_list<_E>::size_type = long unsigned int]()’ from ‘std::initializer_list<double>::size_type {aka long unsigned int}’ to ‘int’ inside { } [-fpermissive]

但如果我把sz{lst.size()}改成sz{(int)lst.size()},那没关系。如果有人能帮我解释一下,我将不胜感激。我在IDE中使用(代码:Blocks IDE(启用的C++0x。编译器GCC(Ubuntu/Linaro 4.6.3-1ubuntu5(4.6.3

#include <iostream>
#include <vector>
#include <list>
#include <initializer_list>  // std::initializer_list
    class Vector
    {
            double* elem;
            int sz;
    public:
            Vector(int s):elem{new double[s]}, sz{s}
            {
                for(int i = 0; i != s; i++)
                    elem[i] = 0;
            }
            ~Vector()
            {
                delete[] elem;
            }
            double& operator[] (int i);
            int size() const;
            void push_back(double);
            //Compilation ERROR: 
            Vector(initializer_list<double> lst):elem{new double[lst.size()]},sz{lst.size()}
            {
                    //copy(lst.begin(), lst.end(), elem);
            }
             //THIS IS OK   
            /* Vector(initializer_list<double> lst):elem{new double[lst.size()]},sz{(int)lst.size()}
            {
                    //copy(lst.begin(), lst.end(), elem);
            } */
    };

问题是您要求将类型为size_t(例如,64无符号整数(的lst.size()隐式转换为int(例如,32位有符号整数(。在大括号初始化的上下文中,这是一个狭窄的转换,具有潜在的危险性。

[dcl.init.list]缩小转换是一种隐式转换。。。从整数类型或无范围枚举类型到不能表示原始类型的所有值的整数类型,。。。

缩小转换规则仅用于支持的初始值设定项列表,即int a{1},而不用于使用()的经典初始化(即int a(1)(。


所以有三条出路:

  1. 使用std::size_t作为sz的类型。sz表示存储块的长度,因此std::size_t是正确的类型。(推荐(

  2. 使用显式转换sz{static_cast<int>(lst.size())}

  3. 在构造函数中使用()而不是{}。(不推荐(

      Vector(initializer_list<double> lst)
      : elem(new double[lst.size()]), sz(lst.size())
      //                               ^^^        ^^^