为什么gcc拒绝`new v<当`v`不是模板时,新的v`?

时间:2017-01-22 00:22:06

标签: c++ c++14 language-lawyer

简单的测试用例:

#include <iostream>
struct v {};
int main() {
    std::cout << __VERSION__ << '\n' << (new v < new v) << '\n';
}

我知道比较指针有一个未指定的结果,但这里没有相关性(类似的例子可以用更多的击键产生,就像后面的coliru片段一样)。

我方便的C ++标准在§14.2第3段中说:

  

名称查找后发现名称是模板名称 operator-function-id literal-operator-id 是指一组重载函数,其中任何成员都是函数模板,如果后跟&lt; ,则&lt; 始终作为分隔符 template-argument-list ,而不是小于运算符。

由于v既不是模板名也不是函数id,我不明白为什么这应该适用。显然,clang

4.2.1 Compatible Clang 3.8.0 (tags/RELEASE_380/final 263969)
1

然而,gcc(6.3.0)抱怨:

main.cpp: In function 'int main()':

main.cpp:4:46: error: 'v' is not a template
     std::cout << __VERSION__ << '\n' << (new v < new v) << '\n';
                                              ^

我(和铿锵)在这里遗漏了什么吗?

没有未指明行为的版本:clang gcc

使用减号运算符而不是小于gcc的版本(无编译错误)

附录

Gcc没有相同的功能问题;使用template functions,它坚持&lt; 必须是模板参数分隔符,而不是non-template functions。这增加了它是一个错误的论点,因此我将其归档为Bug 79192

注意:

如果有人好奇的话,在我试图回答this question的时候出现了这个问题,提问者正在为一个模糊的C ++语言写一个语法,并且偶然发现了上述歧义。我想解释一下C ++使用的解决方案,但是两个编译器之间的差异使得它变得困难。

1 个答案:

答案 0 :(得分:5)

这是一个错误,或者至少错误报告被GCC维护者接受了。

在评论中,Johannes Schaub-litb指出拒绝此构造的代码位于cp/parser.c的第16781行:

  /* There is no valid C++ program where a non-template type is
 followed by a "<".  That usually indicates that the user thought
 that the type was a template.  */
  cp_parser_check_for_invalid_template_id (parser, type, none_type,
                       token->location);

并且注释不正确,因为检查还拒绝其他有效程序,例如

struct A {
   operator A();  
};

void operator<(A (A::*)(), A);

int main() {
   &A::operator A < A();   
}

on coliru