zw3*_*324 50 c++ compiler-construction templates vector lexicographic
我知道当我们在另一个模板中使用模板时,我们应该这样写:
vector<pair<int,int> > s;
如果我们在没有空格的情况下写它:
vector<pair<int,int>> s;
我们会收到一个错误:
嵌套模板参数列表中的`>>'应该是`>>'
我觉得这是可以理解的,但我不禁想知道,在哪种情况下,这真的很模糊?
Joh*_*itb 48
有时你想要它>>.考虑
boost::array<int, 1024>>2> x;
Run Code Online (Sandbox Code Playgroud)
在C++ 03中,这成功地解析并创建了一个大小的数组256.
Arm*_*yan 28
它永远不会含糊不清.事实证明,在C++ 0x中,您不必再在关闭模板之间写入空格>.
问题是编译器更愿意将输入标记为尽可能独立于上下文.由于C++不是一种与上下文无关的语言,因此只添加这一特殊情况并不会使事情变得特别困难.
Dav*_*eas 11
在当前标准中,标记化是贪婪的,因此>>将作为单个标记处理,其方式与a +++ b将被解析为相同a ++ + b.这已经改变了新标准.虽然它需要编译器实现者的更多工作,但总的来说它是值得的(并且一些主要的编译器已经实现了它作为扩展).
C++真的难以解析 - 比大多数其他语言困难得多.它是一种非常一致的语言,但是在对输入进行标记化和理解语法的语法分析之间做了很多工作,看起来对于编译器来说它们应该是简单的,通常不是.
历史" >>"运算符是运算符.它被"识别"为源文件被分解为令牌.然后在语法分析期间(在标记化完成之后很久),在某些上下文中"理解"这些标记.
如果您在标记化时进行了语法分析,那么您有"帮助"以帮助区分" >>"应被视为模板声明(或定义)的两个闭包.然而,历史上这不是历史C++编译器的工作方式.(新编译器在语法分析和标记化之间做了更多反馈,包括更多"预见"以帮助解决这些歧义.)
是的,新的C++ 0x标准改变了这一点,并迫使编译器供应商重新编写他们的实现以消除>>你的情况中的歧义.所以,它永远不会模棱两可.但是,较旧的C++编译器无法处理,因此将代码与' >'字符之间的空间保持兼容可能被认为是"良好实践" .
通过设置适当的 C++ 方言来避免此错误。例如,对于 gcc 4.9,以下文件无法使用 进行编译g++:
#include <vector>
#include <utility>
int main()
{
using namespace std;
vector<pair<int, int>> v; // compile error!
return 0;
}
Run Code Online (Sandbox Code Playgroud)
让我们深入了解一下事情的真相:
#include <iostream>
int main()
{
std::cout << __cplusplus << std::endl;
return 0;
}
Run Code Online (Sandbox Code Playgroud)
仅使用g++ test.cpp此代码编译会打印 199711。尽管 gcc 4.9 于 2014 年发布,但默认的 C++ 方言是带有 GNU 扩展的 C++98。C++98要求我们编写vector<pair<int, int> >. 如果您更喜欢使用或vector<pair<int, int>>进行编译。-std=c++11-std=gnu++11