Col*_*mbo 27 c++ templates language-lawyer c++11
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);
Run Code Online (Sandbox Code Playgroud)
这既不适用于GCC 4.9.2也不适用于Clang 3.5 - 更不用说ICC或VC++了.显然,该>=位被解析为大于或等于运算符.但是,对于[temp.names]/3,这似乎是不正确的:
名称查找(3.4)后发现名称是模板名称或者operator-function-id或literal-operator-id引用一组重载函数,其中任何成员都是函数模板,如果遵循此函数通过a
<,<始终将其视为template-argument-list的分隔符,而不是less-than运算符. 在解析模板参数列表时,第一个非嵌套>138被视为结束分隔符而不是大于运算符.[..] [ 例如:Run Code Online (Sandbox Code Playgroud)template<int i> class X { /* ...*/ }; X< 1>2 > x1; // syntax error X<(1>2)> x2; // OK- 结束例子 ]
138)一种
>包围型-ID的dynamic_cast,static_cast,reinterpret_cast或const_cast,或包围 模板参数个后续的模板id,被认为是嵌套出于本说明书的目的.
我错过了什么或这是一个编译器错误?
Sha*_*our 18
这是最大munch原则的效果,它具有词法分析器,尽可能多地使用字符来形成有效的令牌.草案C++标准部分2.5 [lex.pptoken]中对此进行了介绍,其中说:
否则,下一个预处理标记是可以构成预处理标记的最长字符序列,即使这会导致进一步的词法分析失败.
如上所述的任何情况都需要特定的例外情况,例如这种情况<::,我们可以在下面的代码中看到一个例子:
template<typename T> class SomeClass;
class Class;
SomeClass<::Class>* cls;
Run Code Online (Sandbox Code Playgroud)
这个问题涉及的例外情况,例外情况在最大蒙克规则正上方的子弹中列出:
否则,如果接下来的三个字符是<::且后续字符既不是:nor>,则<被视为预处理器标记本身而不是备用标记<:的第一个字符.
当然还有>你在问题中引用的非嵌套.
注意我们可以看到这>=是来自2.13 [lex.operators]部分的预处理器令牌,它说:
C++程序的词汇表示包括许多预处理标记,这些标记在预处理器的语法中使用,或者转换为运算符和标点符号的标记:
并包含>=在列表中.
>>修复
我们可以从提案中看到修复>>案例:N1757:直角支架(强调我的):
自从引入尖括号以来,C++程序员一直惊讶于两个连续的直角括号必须用空格分隔:
Run Code Online (Sandbox Code Playgroud)#include <vector> typedef std::vector<std::vector<int> > Table; // OK typedef std::vector<std::vector<bool>> Flags; // Error问题是"最大咀嚼"原则的直接后果,以及>>是C++中的有效令牌(右移)这一事实.
这个问题是一个小问题,但是持续存在,令人讨厌,有些令人尴尬.如果成本合理,那么消除意外似乎是值得的.
本文档的目的是解释允许>>被视为两个闭合尖括号的方法,以及讨论产生的问题.提出了一个具体的选择以及将在当前工作文件中实施该提案的措辞.
同时指出>=案例:
值得注意的是,>> =和> =令牌也会出现问题.例如
Run Code Online (Sandbox Code Playgroud)void func(List<B>= default_val1); void func(List<List<B>>= default_val2);这两种形式目前都是不正确的.可能还希望解决这个问题,但本文并未提议这样做.
注意,这个改变打破了与C++ 03的向后兼容性.