为什么在使用#define声明int的vector的vector时没有抛出错误
Why no error is thrown on declaring vector of vector of int using #define
#include <bits/stdc++.h>
using namespace std;
#define vi vector<int>
#define vvi vector<vi>
int main() {
vi v(10, -1);
vvi vv(10, v);
for(int i=0; i<vv.size(); i++){
for(int j=0; j<vv[i].size(); j++){
cout << vv[i][j] << " ";
}
cout << endl;
}
}
当我编译上面的代码时,没有任何错误报告,并且运行良好(见此)。但是,当我使用vector < vector < int>>
声明int的向量的向量时,会发生错误,因为我没有在直角括号之间放置空格。那么,当#define
所做的只是用vector<int>
替换vi
,用vector< vector< int>>
替换vvi
时,为什么在第一种情况下没有报告错误呢?
#define
方法没有得到错误的原因是预处理器正在智能地插入中断。如果您只通过预处理器阶段(例如gcc -E
)传递该代码,您将看到类似以下内容:
int main() {
vector<int> v(10,-1);
vector<vector<int> > vv(10,v); // <<-- see space here.
for(int i=0; i<vv.size(); i++){
for(int j=0; j<vv[i].size(); j++){
cout << vv[i][j] << " ";
}
cout << endl;
}
return 0;
}
发生这种情况的原因与ISO C++标准规定的翻译阶段有关。
C++11(a)的第2.2节指出有九个翻译阶段。阶段3是将源文件拆分为预处理令牌和空白空间。
重要的是标记化,因此vector<vi>
是预处理标记{vector, <, vi, >}
的集合,它是而不是宏替换部分中给出的简单文本。而简单化文本替换:
#define vi vector<int>
#define vvi vector<vi>
vvi xyzzy;
将导致:
vector<vector<int>> xyzzy;
实际上最终得到的是预处理令牌集:
{vector, <, vector, <, int, >, >, WHITESPACE, xyzzy, ;}
然后,在第7阶段,标准规定:
每个预处理令牌都转换为一个令牌。
因此,没有将两个>
令牌重组为一个令牌,尽管对源代码的简单读取可能表明这一点。
(a)请记住,尽管我引用了标准的C++11部分以确保答案是最新的,但这个特定的问题是C++03问题。C++11实际上修复了解析器,使得多个>
字符将关闭一个合理的模板参数列表(C++03总是将其视为右移运算符)。
C++11 14.2, section 3
指定:
解析模板参数列表时,将第一个非嵌套的
>
作为结束分隔符,而不是大于运算符。类似地,第一个非嵌套的>>
被视为两个连续但不同的>
令牌。。。
出现此错误是因为在C++03中,双尖括号被解释为右移运算符>>
。在C++11中,该语言被更改为关闭模板参数,因此它应该在C++11模式下编译而不会出错。您可以通过在闭合尖括号之间留出一个空格来解决此问题,例如vector<vector<int> >
。
另外,不要使用#define
来定义这样的类型别名;请改用typedef
,因为这正是它的用途。
- 尝试将 sf::Texture* 推送到 std::vector 时出错
- 将数据从 std::Vector 存储到 Eigen::Vector 时出错
- 重载运算符时出错<在 sf::Vector 中
- vector::empty()出错,或者我遗漏了什么
- 尝试在<int>构造函数中使用 vector 启动类时出错
- 将std::vector作为模板模板参数传递时出错-在GCC中有效,在MSVC中失败
- 调试断言失败!vector.earse() 调用期间出错
- 使用 std::vector<std::string> myString 时出错
- 仅在发布版本中出错,从 std::vector 复制结构
- 使用包含std::unique_ptr的结构的std::vector声明类时出错
- 删除vector中的指针出错
- 向vector添加共享指针时出错
- 初始化vector时出错
- 在vector排序中使用c++模板函数出错
- 用于初始化 std::vector<std::function<bool(std::string)的初始值设定项列表> >在 g++ 4.9.0 中出错,但使用 Visual
- 在std::vector中压入std::pair时出错
- 使用Struct类型的Vector迭代器出错
- c++编程:将迭代器赋值给vector时出错
- Boost vector insert_element逐个出错
- 将带有字符串成员的结构体对象压入std::vector时出错