而不能在没有空间的情况下编译

而不能在没有空间的情况下编译

本文介绍了为什么“A<0>=0"中的模板id由于大于或等于运算符“>="而不能在没有空间的情况下编译?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

template 使用 A = int;void f(A<0=0);//试图声明一个函数 f 接受 int,//使用默认参数 0//按预期工作://void f(A = 0);

这既不能在 GCC 4.9.2 或 Clang 3.5 上编译 - 更不用说 ICC 或 VC++.显然 >= 位被解析为大于或等于运算符.但是,这对于 [temp.names]/3 来说似乎是不正确的:

名称查找(3.4)后发现名称是模板名称operator-function-idliteral-operator-id 指的是一个集合重载函数的任何成员是函数模板,如果这后面跟着一个<<总是作为template-argument-list 并且从不作为小于运算符.解析模板参数列表时,第一个非嵌套> 作为结束分隔符 而不是一个大于运算符.[..] [ 示例:

template类 X {/* ...*/};X<1>2>x1;//语法错误X (1 2) >x2;//行

——结束示例 ]

是我遗漏了什么还是编译器有问题?

解决方案

这是 最大咀嚼的效果原则,它让词法分析器尽可能多地取字符来形成一个有效的标记.这包含在 C++ 标准部分草案 2.5 [lex.pptoken] 中,它说:

否则,下一个预处理标记是最长的序列可以构成预处理标记的字符,即使会导致进一步的词法分析失败.

任何情况,例如您上面引用的情况,都需要为<:: 制定一个特定的异常,例如,我们可以在以下代码中看到一个示例:

template类 SomeClass;班级;SomeClass* cls;

这个问题中有介绍,例外情况列在最大咀嚼规则上方的项目符号中:>

否则,如果接下来的三个字符是 <:: 并且后续字符既不是 : 也不是 >,则 <本身被视为预处理器标记,而不是作为替代标记的第一个字符 <:.

当然还有您在问题中引用的非嵌套 > .

注意我们可以看到 >= 是来自 2.13 [lex.operators] 部分的预处理器标记,它说:

C++ 程序的词法表示包括许多预处理标记,它们用于预处理器的语法或转换为运算符和标点符号的标记:

并在列表中包含 >=.

>> 修复

我们可以从修复>>案例的提案中看到:N1757:直角括号,上面写着(强调我的):

自从引入尖括号以来,C++ 程序员已经对两个连续的右尖括号的事实感到惊讶必须用空格分隔:

#include typedef std::vector

问题是最大咀嚼"的直接后果原理以及 >> 是 C++ 中的有效标记(右移)这一事实.

这个问题是一个小问题,但持续存在,令人讨厌,而且有点尴尬的问题.如果成本合理,似乎因此值得消除惊喜.

本文档的目的是解释允许>>被视为两个右尖括号,以及讨论产生的问题.提出了具体选项和措辞这将实施当前工作文件中的提案.

同时指出>=的情况:

还值得注意的是,该问题也可以出现在 >>=和 >= 令牌.例如

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

这两种形式目前都是格式错误的.可能需要也解决了这个问题,但本文不建议这样做.

请注意,此更改破坏了与 C++03 的向后兼容性.

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++. Apparently the >= bit is parsed as a greater-or-equal-than operator. However, this seems to be incorrect regarding [temp.names]/3:

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. This is covered in draft C++ standard section 2.5 [lex.pptoken] which says:

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:

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:

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):

Also points out the >= case:

Note, this change broke backward compatibility with C++03.

这篇关于为什么“A&lt;0&gt;=0"中的模板id由于大于或等于运算符“>="而不能在没有空间的情况下编译?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

08-01 10:19