54

我知道当我们在另一个模板中使用模板时,我们应该这样写:

vector<pair<int,int> > s;

如果我们在没有空格的情况下编写它:

vector<pair<int,int>> s;

我们会得到一个错误:

`>>' 应该是嵌套模板参数列表中的 `> >'

我认为这是可以理解的,但我不禁想知道,在什么情况下这真的是模棱两可的?

4

8 回答 8

51

有时你希望它是>>。考虑

boost::array<int, 1024>>2> x;

在 C++03 中,这成功解析并创建了一个 size 数组256

于 2011-07-14T15:07:08.087 回答
29

它永远不会模棱两可。事实证明,在 C++0x 中,您不必再在关闭>的 template 之间写一个空格。

问题是编译器更愿意将输入标记为尽可能独立于上下文。由于 C++ 无论如何都不是一种上下文无关的语言,因此仅添加这种特殊情况不会使事情变得特别困难。

于 2011-07-14T14:56:32.873 回答
11

在当前标准中,标记化是贪婪的,因此>>将作为单个标记处理,与a +++ b解析为a ++ + b. 这已经改变和新的标准。虽然它需要编译器实现者做更多的工作,但总的来说它被认为是值得的(并且一些主要的编译器已经将其作为扩展实现了)。

于 2011-07-14T15:03:38.790 回答
7

C++ 真的很难解析——比大多数其他语言都难。它是一种非常一致的语言,但是在对输入进行标记和理解语法的语法分析之间做了很多工作,以至于对于编译器来说看起来应该很简单的事情通常不是。

历史上的“ >>”运算符是一个运算符。它被“识别”为源文件被分解为标记。这些标记随后在语法分析期间在某些上下文中被“理解”(在标记化完成很久之后)。

如果您在标记化时进行了语法分析那么您有“帮助”来帮助区分“ >>”应该被视为模板声明(或定义)的两个闭包。然而,从历史上看,这并不是历史 C++ 编译器的工作方式。(新的编译器在语法分析和标记化之间做更多的反馈,包括更多的“前瞻”来帮助解决这些歧义。)

是的,新的 C++0x 标准改变了这一点,并迫使编译器供应商重新编写他们的实现以消除 " >>" 在你的情况下的歧义。所以,未来永远不会模棱两可。>但是,较旧的 C++ 编译器无法处理此问题,因此暂时将代码与 ' ' 字符之间的空格保持兼容可能被认为是“好习惯” 。

于 2011-07-14T15:06:02.253 回答
3

通过设置适当的 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

于 2015-07-19T06:27:32.210 回答
1

这取决于编译器。Visual Studio 不强制要求这样做,即在 g++ 产生错误时两者都有效。我认为这取决于编译器的实现。

于 2011-07-14T15:00:08.223 回答
0

我在用 C++ 编写一个类时遇到了这个问题,我通过执行以下操作解决了这个问题:

产生与前面提到的相同错误的行:

findAndDrawContoursFrame(cv::Mat&,cv::Mat&,std::vector<std::vector<cv::Point»&);

通过 GCC 交叉编译器并运行的行:

findAndDrawContoursFrame(cv::Mat&,cv::Mat&,std::vector< std::vector<cv::Point> >&);

对我来说,这只是对声明解释的错误。

于 2016-09-16T06:29:46.170 回答
0

流语法

cin >> var;

VS

嵌套模板语法

For<Bar<Barz>>

编译器的第一阶段,词法分析器将无法识别。

于 2019-06-22T19:52:30.187 回答