对整数向量的向量进行统一初始化

Uniform initialization on a vector of vectors of integers

本文关键字:向量 初始化 整数      更新时间:2023-10-16

C++11

该程序初始化一个名为myVecint vectorvector,然后使用循环打印出每个内部vector的元素。但当我试着看看当我使用额外的花括号时会发生什么时,我得到了意想不到的结果。以下内容也在LiveWorkSpace上,以便在编译器之间轻松切换。g++ 4.8.0只能编译到myVec[5]clang++ 3.2编译所有内容:

#include <iostream>
#include <vector>
int main()
{
    std::vector<std::vector<int>> myVec =
    {
        /* myVec[0] */ {1, 2},
        /* myVec[1] */ {},
        /* myVec[2] */ {{}},
        /* myVec[3] */ { {}, {} },
        /* myVec[4] */ { {}, {}, {} },
        /* myVec[5] */ {{{}}}
        /* myVec[6] */  // , { {{}}, {{}} }       // g++ 4.8.0 COMPILER ERROR
        /* myVec[7] */  // , {{{{}}}}             // g++ 4.8.0 COMPILER ERROR
        /* myVec[8] */  // , { {{{}}}, {{{}}} }   // g++ 4.8.0 COMPILER ERROR
    };
    // loop for printing
    for (unsigned int i = 0; i < myVec.size(); ++i)
    {
        std::cout << "myVec[" << i << "]: ";
        for (unsigned int j = 0; j < myVec.at(i).size(); ++j)
        {
            std::cout << myVec.at(i).at(j) << ", ";
        }
        std::cout << std::endl;
    }
    return 0;
}

实际g++ 4.8.0输出:

myVec[0]: 1, 2,
myVec[1]:
myVec[2]: 0,
myVec[3]: 0, 0,
myVec[4]: 0, 0, 0,
myVec[5]: 0,

分析:

myVec[0]:{1, 2}:

得到了预期的输出。

myVec[1]:{}:

得到了预期的输出。

myVec[2]:{{}}:

这是int0的矢量。内部大括号将int初始化为0

myVec[3]:{ {}, {} }:

两个内部大括号将一个int初始化为0

myVec[4]:{ {}, {}, {} }:

三个内部大括号将每个int初始化为0

myVec[5]:{{{}}}:

我想在myVec[2]中再添加一组大括号,看看在出现编译器错误之前添加大括号能走多远。我不明白为什么要编译它,为什么它的元素打印为0

例如,int j = {}j初始化为0vector<vector<int>> v = { {{}} }将最里面的{}初始化为int0,使其等效于vector<vector<int>> v = { {0} }。那么,什么是vector<vector<int>> u = { {{{}}} },为什么要编译呢?

假设的myVec[6]:{ {{}}, {{}} }:

按照与上面相同的模式,我想制作一个包含两组双花括号的向量。但这并不能编译,我不明白为什么这会打破给我多个零的模式。

假设的myVec[7]:{{{{}}}}:

我想在myVec[5]中再添加一组大括号,看看在出现编译器错误之前添加大括号能走多远。我不明白为什么这会破坏模式而不编译。

假设的myVec[8]:{ {{{}}}, {{{}}} }:

我想将myVec[7]扩展到,以生成一个具有两组三个大括号的向量。我不明白为什么这也不能编译。

如果myVec[5]之前的所有内容都编译了,为什么其余的都不编译呢?

尝试编译此代码。它应该解释你的问题:

int i = {};   // initializes i to int()
int j = {{}}; // fails to compile

为什么{{{}}}在您的代码中被接受似乎是一个与如何处理ctor有关的gcc错误(需要澄清(:

struct foo {
    foo( std::initializer_list<int> ) {}
};
void f()
{
   foo bar1( {{{}}} ); // compiles fine
   foo bar2 = {{{}}}; // compiles fine
}

编辑(感谢Johannes Schaub(-删除复制因子使第一个变体无法编译:

struct foo {
    foo( std::initializer_list<int> ) {}
    foo( const foo& ) = delete;
};
void f()
{
   foo bar1( {{{}}} ); // fails to compile: use of deleted function ‘foo::foo(const foo&)’
   foo bar2 = {{{}}}; // still compiles, neither deleting move ctor, nor assignment operator does not affect that, is copy ctor of std::initializer_list involved?
}

对于成员功能,它失败了:

struct foo {
    void moo( std::initializer_list<int> ) {}
};
void f()
{
   foo bar;
   bar.moo( {{{}}} ); // fails to compile
}

此代码也失败:

std::initializer_list<int> l = {{{}}}; // fails to compile

std::vector:的ctor与成员函数的情况相同

void f()
{
    std::vector<int> v( {{{}}} ) // compiles fine;
    v.assign( {{{}}} ); // fails to compile
};

gcc版本4.7.2(Ubuntu/Linaro 4.7.2-2ubuntu1(