简体   繁体   English

为什么“A <0> = 0”中的template-id由于大于或等于运算符“> =”而无法在没有空格的情况下进行编译?

[英]Why does the template-id in “A<0>=0” not compile without space because of the greater-or-equal-than operator “>=”?

template <int>
using A = int;

void f(A<0>=0);   // Attempting to declare a function f taking int,
                  // with the default argument 0

// Works as expected:
// void f(A<0> = 0);

This neither compiles on GCC 4.9.2 nor Clang 3.5 - let alone ICC or VC++. 这既不适用于GCC 4.9.2也不适用于Clang 3.5 - 更不用说ICC或VC ++了。 Apparently the >= bit is parsed as a greater-or-equal-than operator. 显然, >=位被解析为大于或等于运算符。 However, this seems to be incorrect regarding [temp.names]/3: 但是,对于[temp.names] / 3,这似乎是不正确的:

After name lookup (3.4) finds that a name is a template-name or that an operator-function-id or a literal- operator-id refers to a set of overloaded functions any member of which is a function template, if this is followed by a < , the < is always taken as the delimiter of a template-argument-list and never as the less-than operator. 名称查找(3.4)后发现名称是模板名称或者operator-function-idliteral-operator-id引用一组重载函数,其中任何成员都是函数模板,如果遵循此函数通过<<始终作为模板参数列表的分隔符,而不是作为小于运算符。 When parsing a template-argument-list , the first non-nested > 138 is taken as the ending delimiter rather than a greater-than operator. 解析模板参数列表时 ,第一个非嵌套> 138作为结束分隔符而不是大于运算符。 [..] [ Example: [..] [ 例如:

 template<int i> class X { /* ...*/ }; X< 1>2 > x1; // syntax error X<(1>2)> x2; // OK 

— end example ] - 结束例子 ]

138) A > that encloses the type-id of a dynamic_cast , static_cast , reinterpret_cast or const_cast , or which encloses the template-argument s of a subsequent template-id , is considered nested for the purpose of this description. 138)包含dynamic_caststatic_castreinterpret_castconst_casttype-id的A >或包含后续template-idtemplate-argument的A >被认为是嵌套的,用于本说明的目的。

Am I missing something or is this a compiler bug? 我错过了什么或这是一个编译器错误?

This an effect of the maximal munch principle , which has the lexical analyzer take as many characters as possible to form a valid token. 这是最大munch原则的效果,它具有词法分析器,尽可能多地使用字符来形成有效的令牌。 This is covered in draft C++ standard section 2.5 [lex.pptoken] which says: 草案C ++标准第2.5[lex.pptoken]中对此进行了介绍,其中说:

Otherwise, the next preprocessing token is the longest sequence of characters that could constitute a preprocessing token, even if that would cause further lexical analysis to fail. 否则,下一个预处理标记是可以构成预处理标记的最长字符序列,即使这会导致进一步的词法分析失败。

Any cases such as the one you cite above need a specific exception carved out such as this case for <:: , we can see an example in the following code: 任何情况,例如你上面引用的那个都需要一个特定的异常,例如<::这种情况,我们可以在下面的代码中看到一个例子:

template<typename T> class SomeClass;
class Class;

SomeClass<::Class>* cls;

which is covered in this question , the exception is listed in the bullet just above the maximal munch rule: 这个问题涉及的例外情况,例外情况在最大蒙克规则正上方的子弹中列出:

Otherwise, if the next three characters are <:: and the subsequent character is neither : nor >, the < is treated as a preprocessor token by itself and not as the first character of the alternative token <:. 否则,如果接下来的三个字符是<::且后续字符既不是:nor>,则<被视为预处理器标记本身而不是备用标记<:的第一个字符。

and of course the non-nested > which you cite in your question. 当然还有你在问题中引用的非嵌套>

Note we can see that >= is a preprocessor token from section 2.13 [lex.operators] which says: 注意我们可以看到>=2.13[lex.operators]中的预处理器令牌,它说:

The lexical representation of C++ programs includes a number of preprocessing tokens which are used in the syntax of the preprocessor or are converted into tokens for operators and punctuators: C ++程序的词汇表示包括许多预处理标记,这些标记在预处理器的语法中使用,或者转换为运算符和标点符号的标记:

and includes >= in the list. 并在列表中包含>=

The >> fix >>修复

We can see from the proposal that fixed the >> case: N1757: Right Angle Brackets which says ( emphasis mine ): 我们可以从提案中看到修复了>>案例: N1757:直角括号中的( 强调我的 ):

Ever since the introduction of angle brackets, C++ programmers have been surprised by the fact that two consecutive right angle brackets must be separated by whitespace: 自从引入尖括号以来,C ++程序员一直惊讶于两个连续的直角括号必须用空格分隔:

 #include <vector> typedef std::vector<std::vector<int> > Table; // OK typedef std::vector<std::vector<bool>> Flags; // Error 

The problem is an immediate consequence of the the “maximum munch” principle and the fact that >> is a valid token (right shift) in C++. 问题是“最大咀嚼”原则直接后果,以及>>是C ++中的有效令牌(右移)这一事实。

This issue is a minor, but persisting, annoying, and somewhat embarrassing problem. 这个问题是一个小问题,但是持续存在,令人讨厌,有些令人尴尬。 If the cost is reasonable, it seems therefore worthwhile to eliminate the surprise. 如果成本合理,那么消除意外似乎是值得的。

The purpose of this document is to explain ways to allow >> to be treated as two closing angle brackets, as well as to discuss the resulting issues. 本文档的目的是解释允许>>被视为两个闭合尖括号的方法,以及讨论产生的问题。 A specific option is proposed along with wording that would implement the proposal in the current working paper. 提出了一个具体的选择以及将在当前工作文件中实施该提案的措辞。

Also points out the >= case: 同时指出>=案例:

It is also worth noting that the problem can also occur with the >>= and >= tokens . 值得注意的是,>> =和> =令牌也会出现问题。 For example 例如

 void func(List<B>= default_val1); void func(List<List<B>>= default_val2); 

Both of these forms are currently ill-formed. 这两种形式目前都是不正确的。 It may be desirable to also address this issue, but this paper does not propose to do so. 可能还希望解决这个问题,但本文并未提议这样做。

Note, this change broke backward compatibility with C++03 . 注意,这个改变打破了与C ++ 03的向后兼容性

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM