std :: initializer_list不允许缩小范围

时间:2014-05-03 06:41:45

标签: c++ c++11

我有这个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);
            } */
    };

1 个答案:

答案 0 :(得分:3)

问题是您要求将lst.size() size_t类型int(例如64位无符号整数)隐式转换为int a{1}(例如32位有符号)。在大括号初始化的上下文中,这是一个缩小的转换,这可能是危险的。

  

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

缩小转化规则仅用于支持初始化列表,即用于(),而不用于使用int a(1)的经典初始化,即用于std::size_t


所以有三种方法:

  1. 使用sz作为sz的类型。 std::size_t表示内存块的长度,因此sz{static_cast<int>(lst.size())}是正确的类型。 (建议)

  2. 使用显式转化()

  3. 在构造函数中使用{}而不是 Vector(initializer_list<double> lst) : elem(new double[lst.size()]), sz(lst.size()) // ^^^ ^^^ 。 (不推荐)

    {{1}}