#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;
}
}
Run Code Online (Sandbox Code Playgroud)
当我编译上面的代码时,没有报告错误,它运行正常(见这个).但是当我声明int的向量向量使用vector < vector < int>>错误时,因为我没有在右尖括号之间放置一个空格.那么,为什么在第一种情况下没有报告错误,#define只需要替换viwith vector<int>和vviwith 的出现vector< vector< int>>?
您没有得到该#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;
}
Run Code Online (Sandbox Code Playgroud)
这种情况发生的原因与ISO C++标准所规定的翻译阶段有关.
C++ 11 (a)的 2.2节规定有九个翻译阶段.阶段3是将源文件拆分为预处理令牌和空白区域.
重要的是令牌化,因此这vector<vi>是一组预处理令牌{vector, <, vi, >},它不是宏替换部分中给出的简单文本.虽然简单的文字替换:
#define vi vector<int>
#define vvi vector<vi>
vvi xyzzy;
Run Code Online (Sandbox Code Playgroud)
会导致:
vector<vector<int>> xyzzy;
Run Code Online (Sandbox Code Playgroud)
你居然结了是预处理标记集:
{vector, <, vector, <, int, >, >, WHITESPACE, xyzzy, ;}
Run Code Online (Sandbox Code Playgroud)
然后,在阶段7,标准规定:
每个预处理令牌都转换为令牌.
因此,>尽管对源的简单读取可能表明这两个令牌没有重新组合成单个令牌.
(a)请记住,尽管我引用了标准的C++ 11部分以确保答案是最新的,但这个特殊问题是C++ 03.C++ 11实际上修复了解析器,以便多个>字符将合理地关闭模板参数列表(C++ 03始终将其视为右移运算符).
C++11 14.2, section 3 指定:
解析模板参数列表时,第一个非嵌套
>被视为结束分隔符而不是大于运算符.同样,第一个非嵌套>>被视为两个连续但不同的>标记......
| 归档时间: |
|
| 查看次数: |
134 次 |
| 最近记录: |