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

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

2023-12-30

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

这既不能编译GCC 4.9.2 或 Clang 3.5 http://coliru.stacked-crooked.com/a/ca537ab1efae307e- 更不用说ICC或VC++了。显然是>=bit 被解析为大于或等于运算符。然而,这对于 [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. When parsing a template-argument-list, the first non-nested >138 is taken as the ending delimiter rather than a greater-than operator. [..] [ Example:

template<int i> class X { /* ...*/ };

X< 1>2 > x1; // syntax error
X<(1>2)> x2; // OK

—结束示例 ]

138) A > that encloses the type-id of a dynamic_cast, static_cast, reinterpret_cast or const_cast, or which encloses the template-arguments of a subsequent template-id, is considered nested for the purpose of this description.

我错过了什么还是这是一个编译器错误?


这是一个效果最大蒙奇原理 http://en.wikipedia.org/wiki/Maximal_munch,它让词法分析器采用尽可能多的字符来形成有效的标记。 C++ 标准草案部分涵盖了这一点2.5 [lex.pptoken]其中说:

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

任何情况(例如您上面引用的情况)都需要制定特定的例外情况,例如本例<::,我们可以在下面的代码中看到一个例子:

template<typename T> class SomeClass;
class Class;

SomeClass<::Class>* cls;

其中涵盖这个问题 https://stackoverflow.com/q/3952648/1708801,例外情况列在最大咀嚼规则上方的项目符号中:

否则,如果接下来的三个字符是 <:: :>,则

当然还有非嵌套的>你在问题中引用的。

注意我们可以看到>=是来自节的预处理器标记2.13 [词法运算符]其中说:

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

并包括>=在列表中。

>> 修复

从修正的提案中我们可以看到>> case: N1757:直角括号 http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2005/n1757.html其中说(强调我的):

自从引入尖括号以来,C++ 程序员就 两个连续的直角括号让我感到惊讶 必须用空格分隔:

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

问题是一个“最大程度咀嚼”的直接后果 原则事实上 >> 在 C++ 中是一个有效的标记(右移)。

这个问题虽小,但持续存在,令人烦恼,而且有点 尴尬的问题。如果成本合理的话,看来 值得消除惊喜。

本文档的目的是解释如何让 >> 被视为两个右尖括号,以及讨论 由此产生的问题。提出了具体选项以及措辞 这将落实当前工作文件中的提案。

还指出>= case:

还值得注意的是,这个问题可以也与 >>= 一起出现 和 >= 标记。例如

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

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

注意,这个改变破坏了与 C++03 的向后兼容性 https://stackoverflow.com/a/23063914/1708801.

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

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

随机推荐