当前位置:  开发笔记 > 编程语言 > 正文

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

如何解决《当"v"不是模板时,为什么gcc会拒绝`newv<newv`?》经验,为你挑选了1个好方法。

简单的测试案例:

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

我知道比较指针有一个未指定的结果,但这里没有相关性(类似的例子可以通过更多的击键产生,如在后面的coliru片段中).

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

在名称查找后发现名称是模板名称或者operator-function-idliteral-operator-id引用一组重载函数,其中任何成员都是函数模板,如果后面跟着a <,将<始终作为一个的分隔符模板参数列表,从不为小于运算符.

既然v既不是模板名也不是函数id,我不明白为什么这应该适用.而且,显然,它都没有铿锵作响:

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没有相同的功能问题; 使用模板函数时,它坚持<必须是模板参数分隔符,而不是非模板函数.这增加了它是一个bug的论点,因此我将其归档为Bug 79192.


注意:

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



1> rici..:

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

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

  /* 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();   
}

(在coliru上)

推荐阅读
携手相约幸福
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有