C++ 模板中的模板:为什么在嵌套的模板参数列表中“`>>' 应该是`> >'”

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/6695261/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-28 20:33:22  来源:igfitidea点击:

Template within template: why "`>>' should be `> >' within a nested template argument list"

c++templatescompiler-constructionvectorlexicographic

提问by zw324

I know that when we are using template inside another template, we should write it like this:

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

vector<pair<int,int> > s;

vector<pair<int,int> > s;

and if we write it without the whitespace:

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

vector<pair<int,int>> s;

vector<pair<int,int>> s;

we will get an error:

我们会得到一个错误:

`>>' should be `> >' within a nested template argument list

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

I see this is understandable, but I just can't help but wondering, in which cases will this be really ambiguous?

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

采纳答案by Johannes Schaub - litb

Sometimes you wantit to be >>. Consider

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

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

In C++03 this successfully parses and creates an array of size 256.

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

回答by Armen Tsirunyan

It won't ever be ambiguous. This is proven by the fact that in C++0x you don't have to write a space between closing template >s any more.

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

The thing is that the compilers would prefer to tokenize the input as context-independently as possible. Since C++ is not a context independent language anyway, adding just this one special case isn't going to make things particularly harder.

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

回答by David Rodríguez - dribeas

In the current standard, tokenization is greedy, so >>will be processed as a single token, in the same way that a +++ bwill be parsed as a ++ + b. This has changed and the new standard. While it requires more work from the compiler implementors, it was deemed that overall it is worth it (and some major compilers already implement that as an extension anyway).

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

回答by charley

C++ is really incredibly hard to parse -- much more difficult than most other languages. It is a very consistent language, but so much work is done between tokenizing the input and understanding the grammatical analysis of the syntax, that things that seem like they should be simple for a compiler, often are NOT.

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

The historical ">>" operator is an operator. It is "identified" as the source file is broken into tokens. Those tokens are then later "understood" in some context during grammatical analysis (long after tokenization is complete).

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

If you did grammatical analysis whileyou tokenized, then you have "helps" to assist in the distinction that ">>" should be considered as two closures to a template declaration (or definition). Yet, this is historically not how historical C++ compilers work. (New compilers do more feedback between grammatical analysis and tokenization, including more "look-aheads" to help resolve these ambiguities.)

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

Yes, the new C++0x standard changes that, and forces compiler vendors to re-write their implementations to disambiguate ">>" in your case. So, it will never be ambiguous going forward. However, older C++ compilers cannot handle that, so it may be considered "good practice" to keep your code compatible with the space between the '>' characters for now.

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

回答by iBrAaAa

It depends on the compiler. Visual Studio does not mandate this i.e. both works while g++ produces an error. I think that this depends on the compiler implementation.

这取决于编译器。Visual Studio 不强制执行此操作,即在 g++ 产生错误时两者都有效。我认为这取决于编译器的实现。

回答by Andreas Spindler

Avoid this error by setting an appropriate C++ dialect. For example, with gcc 4.9 the following file does not compile with g++:

通过设置适当的 C++ 方言来避免此错误。例如,对于 gcc 4.9,以下文件不会编译为g++

#include <vector>
#include <utility>

int main()
{
    using namespace std;
    vector<pair<int, int>> v; // compile error!
    return 0;
}

Let's get to the bottom of things:

让我们深入了解事情的本质:

#include <iostream>

int main()
{
    std::cout << __cplusplus << std::endl;
    return 0;
}

Compiled with just g++ test.cppthis code prints 199711. Although gcc 4.9 was released in 2014 the default C++ dialect is C++98 with GNU extensions. C++98 requires us to write vector<pair<int, int> >. If you like vector<pair<int, int>>more compile with -std=c++11or -std=gnu++11.

仅使用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

回答by Mani

Stream Syntax

流语法

cin >> var;

cin >> var;

Vs

对比

Nested Template Syntax

嵌套模板语法

For<Bar<Barz>>

For<Bar<Barz>>

First phase of Compiler, lexical analyser will not be able to recognise.

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

回答by Ricardo Medeiros

I had this issue programing a class in c++, and i solved it by doing the following:

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

Line that produced the same error mentioned here before:

产生这里之前提到的相同错误的行:

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

Line that passed through GCC Cross Compiler and Worked:

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

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

For me it was just an error on the interpretation of the statement.

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