tags: C++ Debug STL

问题

先来看这样一份代码:

vector<vector<int>> v(10, vector<int>(10));

没有任何问题, 初始化一个10*10的全零二维数组, 但是, 如果在类内:

class P {
private:
vector<vector<int>> v(10, vector<int>());
public:
P() {}
void print() {
for (auto i : v) {
for (auto j : i) cout << j << " ";
cout << endl;
}
}
};

就会报错:

// clang++: error: expected parameter declarator
// g++: error: expected ',' or '...' before numeric constant
// error: expected identifier before numeric constant

那么这是为什么呢?

用一维数组试试:

class P {
private:
vector<int> v(10);
public:
P() {}
void print() {
for (auto i : v) cout << i << " ";
}
};

还是一样的情况…

那么换初始化列表(C++11)呢?

vector<vector<int>> v{{1, 2}, {3, 4, 5}};

这样就可以了…

解决

​declaring a vector - C++ Forum (cplusplus.com)​​;

后来看cplusplus, 想起来了Effective STL item6, 当心C++编译器烦人的分析机制, 发现原来是括号的问题, 导致了二义性, 但是这只是作为类内数据成员来看的, 其他时候并不用担心, 解决方案是:

class P {
private:
vector<int> v = vector<int>(10);

public:
P() {}
void print() {
for (auto i : v) cout << i << " ";
}
};

void t1() {
//
P p;
p.print();
}
int main(int argc, char const *argv[]) {
t1();
return 0;
}

针对二维数组的初始化:

vector<vector<int>> v = vector<vector<int>>(10, vector<int>(10));

虽然冗余, 至少可行, 后来发现可以用一致性初始化.

#include <vector>
#include <iostream>
using namespace std;


class P {
private:
vector<int> v;

public:
P() : v(10) {}
void print() {
for (auto i : v) cout << i << " ";
}
};

void t1() {
//
P p;
p.print();
}
int main(int argc, char const *argv[]) {
t1();
return 0;
}

相当完美.

二维数组类似, 只需要用同样的初始化方式即可:

#include <vector>
#include <iostream>
using namespace std;


class P {
private:
vector<vector<int>> v;

public:
P() : v(10, vector<int>(10)) {}
void print() {
for (auto i : v) {
for (auto j : i) cout << j << " ";
cout << endl;
}
}
};

void t1() {
//
P p;
p.print();
}
int main(int argc, char const *argv[]) {
t1();
return 0;
}