模板中的模板:为什么“>>”应该是“>” >'在嵌套模板参数列表中”
我知道当我们在另一个模板中使用模板时,我们应该这样写:
vector
如果我们不带空格地编写它:
vector
我们会得到一个错误:
`>>'应该是“>” >'在嵌套模板参数列表中
我认为这是可以理解的,但我只是忍不住想知道,在什么情况下这真的会很不明确?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(8)
有时您希望它是
>>
。考虑在 C++03 中,这成功地解析并创建了一个大小为
256
的数组。Sometimes you want it to be
>>
. ConsiderIn C++03 this successfully parses and creates an array of size
256
.永远不会有歧义。事实证明了这一点,在 C++0x 中,您不必再在关闭模板
>
之间编写空格。问题是编译器更愿意尽可能独立于上下文对输入进行标记。由于 C++ 无论如何都不是一种上下文无关的语言,因此仅添加这个特殊情况并不会让事情变得特别困难。
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.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++03)中,标记化是贪婪的,因此
>>
将被作为单个标记进行处理,与a +++ b
a +++ b 相同。 code> 将被解析为a ++ + b
。这在新标准 (C++11) 中发生了变化。虽然它需要编译器实现者做更多的工作,但人们认为总体而言这是值得的(而且一些主要编译器已经将其实现为扩展)。In the current standard (C++03), tokenization is greedy, so
>>
will be processed as a single token, in the same way thata +++ b
will be parsed asa ++ + b
. This has changed in the new standard (C++11). 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).C++ 确实非常难以解析——比大多数其他语言都困难得多。它是一种非常一致的语言,但是在对输入进行标记和理解语法的语法分析之间做了很多工作,以至于对于编译器来说看起来应该很简单的事情通常并非如此。
历史上的“
>>
”运算符是一个运算符。当源文件被分解为标记时,它被“识别”。然后,这些标记在语法分析期间(在标记化完成后很久)在某些上下文中被“理解”。如果您在标记化时进行了语法分析,那么您可以“帮助”来帮助区分“
>>
”应该被视为模板的两个闭包声明(或定义)。然而,这并不是历史上 C++ 编译器的工作方式。 (新编译器在语法分析和标记化之间进行更多反馈,包括更多“前瞻”以帮助解决这些歧义。)是的,新的 C++0x 标准改变了这一点,并迫使编译器供应商重新编写其实现以消除歧义在你的情况下为“
>>
”。所以,今后的发展,绝不会含糊。但是,较旧的 C++ 编译器无法处理该问题,因此目前保持代码与 '>
' 字符之间的空格兼容可能被认为是“良好实践”。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.
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 while you 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.)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++ 方言来避免此错误。例如,在 gcc 4.9 中,以下文件无法使用
g++
进行编译:让我们深入了解一下:
仅使用
g++ test.cpp
进行编译,此代码会打印 199711。 gcc 4.9 于 2014 年发布,默认的 C++ 方言是带有 GNU 扩展的 C++98。 C++98 要求我们写成vector >
。如果您更喜欢vector>
,请使用-std=c++11
或-std=gnu++11
进行编译代码>.Avoid this error by setting an appropriate C++ dialect. For example, with gcc 4.9 the following file does not compile with
g++
:Let's get to the bottom of things:
Compiled with just
g++ test.cpp
this 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 writevector<pair<int, int> >
. If you likevector<pair<int, int>>
more compile with-std=c++11
or-std=gnu++11
.这取决于编译器。 Visual Studio 不强制要求这样做,即两者都可以工作,而 g++ 会产生错误。我认为这取决于编译器的实现。
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.
我在用 C++ 编写一个类时遇到了这个问题,我通过执行以下操作解决了这个问题:
产生之前提到的相同错误的行:
通过 GCC 交叉编译器并工作的行:
对我来说,这只是解释上的错误声明。
I had this issue programing a class in c++, and i solved it by doing the following:
Line that produced the same error mentioned here before:
Line that passed through GCC Cross Compiler and Worked:
For me it was just an error on the interpretation of the statement.
cin >> var;
VS
For>
编译器第一阶段,词法分析器将无法识别。
cin >> var;
Vs
For<Bar<Barz>>
First phase of Compiler, lexical analyser will not be able to recognise.