我知道当我们在另一个模板中使用模板时,我们应该这样写:
vector<pair<int,int> > s;
如果我们在没有空格的情况下写它:
vector<pair<int,int>> s;
我们会收到错误:
`&GT;&GT;”应该是`&gt; &GT;”在嵌套模板参数列表
中
我觉得这是可以理解的,但我不禁想知道,在哪种情况下,这真的很模糊?
答案 0 :(得分:48)
有时候你希望它是>>
。考虑
boost::array<int, 1024>>2> x;
在C ++ 03中,这成功解析并创建了一个大小为256
的数组。
答案 1 :(得分:25)
它永远不会含糊不清。事实证明,在C ++ 0x中,您不必再在关闭模板>
之间写入空格。
问题在于编译器更愿意将输入标记为尽可能独立于上下文。由于C ++不是一种与上下文无关的语言,因此只添加这一特殊情况并不会使事情变得特别困难。
答案 2 :(得分:10)
在当前标准中,标记化是贪婪的,因此>>
将作为单个标记处理,就像a +++ b
将被解析为a ++ + b
一样。这已经改变了新标准。虽然它需要编译器实现者的更多工作,但总的来说它是值得的(并且一些主要的编译器已经实现了它作为扩展)。
答案 3 :(得分:6)
C ++非常难以解析 - 比大多数其他语言困难得多。它是一种非常一致的语言,但是在对输入进行标记化和理解语法的语法分析之间做了很多工作,对于编译器来说它们看起来应该很简单,通常都不是。
历史“>>
”运算符是运算符。它被“识别”为源文件被分解为令牌。然后,在语法分析期间(在标记化完成之后很久),这些标记随后在某些上下文中被“理解”。
如果您在进行语法分析时进行了标记化,那么您可以“帮助”区分“>>
”应被视为模板声明的两个闭包(或者定义)。然而,历史上这不是历史C ++编译器的工作方式。 (新编译器在语法分析和标记化之间进行更多反馈,包括更多“预见”以帮助解决这些歧义。)
是的,新的C ++ 0x标准对此进行了更改,并强制编译器供应商重新编写其实现,以消除您的情况中的“>>
”歧义。所以,它永远不会模棱两可。但是,较旧的C ++编译器无法处理,因此将代码与“>
”字符之间的空格保持兼容可能被视为“良好做法”。
答案 4 :(得分:1)
这取决于编译器。 Visual Studio没有强制要求它,即两者都有效,而g ++产生错误。我认为这取决于编译器的实现。
答案 5 :(得分:1)
通过设置适当的C ++方言来避免此错误。例如,使用gcc 4.9,以下文件无法使用g++
进行编译:
#include <vector>
#include <utility>
int main()
{
using namespace std;
vector<pair<int, int>> v; // compile error!
return 0;
}
让我们深入了解事情:
#include <iostream>
int main()
{
std::cout << __cplusplus << std::endl;
return 0;
}
仅用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
进行更多编译。
答案 6 :(得分:0)
流语法
cin >> var;
Vs
嵌套模板语法
For<Bar<Barz>>
在编译器的第一阶段,词法分析器将无法识别。
答案 7 :(得分:-1)
我有这个问题用c ++编写一个类,我通过执行以下操作解决了这个问题:
之前产生相同错误的行:
findAndDrawContoursFrame(cv::Mat&,cv::Mat&,std::vector<std::vector<cv::Point»&);
通过GCC交叉编译器和工作的行:
findAndDrawContoursFrame(cv::Mat&,cv::Mat&,std::vector< std::vector<cv::Point> >&);
对我而言,对声明的解释只是一个错误。