用C++ 11编译后模板函数被破坏

Ano*_*ous 3 c++ compiler-errors c++11

我有一个非常简单的模板函数来比较rank两个字段structs:

template<typename T>
bool comp_rank(const T &a, const T &b){
    return a.rank < b.rank;
}
Run Code Online (Sandbox Code Playgroud)

这很好,直到我编译-std=c++11.现在,我收到了错误

error: parameter "b" is not a type name
      return a.rank < b.rank;
                      ^

./src/util.h(123): error: expected a ">"
      return a.rank < b.rank;
                       ^
Run Code Online (Sandbox Code Playgroud)

是什么赋予了?这似乎是基本的语法,我惊讶地发现在C++ 11之后发生了变化.

And*_*dyG 7

编辑:我在这里向gcc提交了一个错误报告.它目前尚未证实.

鉴于您接受了@Klaus的回答,您的代码看起来像这样(感谢@krzaq):

#include <type_traits>

using namespace std;

struct A{ int rank; };

template<typename T>
bool comp_rank(const T &a, const T &b){
    return a.rank < b.rank;
}

int main()
{
    A a{42}, b{0};
    comp_rank(a, b);
}
Run Code Online (Sandbox Code Playgroud)

gcc(9.0.0和更早版本都经过测试),并且clang(8.0.0及更早版本已经过测试)拒绝此代码,理由是他们期望这id-expression a.rank<是模板的开始.根据标准,这是错误的解释.见[basic.lookup.classref]

在类成员访问表达式中,如果.->标记后面紧跟着标识符后跟a <,则 必须查找标识符以确定它<是模板参数列表的开头还是小于运算符.首先在对象表达式的类中查找标识符.如果未找到标识符,则在整个postfix-expression的上下文中查找它,并命名一个类模板.

编译器应该查找a.rank并发现它是类的整数成员A.MSVC 19.00.23506编译得很好


Kla*_*aus 5

你的问题是你使用

using namespace std;
Run Code Online (Sandbox Code Playgroud)

因为c ++ 11引入了一个模板 rank

见这里:https://en.cppreference.com/w/cpp/types/rank

如果你删除using声明,一切都会再次编译好!

这是gcc 8.2.1给出的错误消息

main.cpp: In function 'bool comp_rank(const T&, const T&)':
main.cpp:41:23: error: type/value mismatch at argument 1 in template parameter list for 'template<class> struct std::rank'
    return a.rank < b.rank;
Run Code Online (Sandbox Code Playgroud)

using namespace ...反正使用它不是一个好主意.你给了一个很好的例子;)

  • @Klaus:你可能是对的,但是我们无法确定,直到OP在这个评论帖中发帖[mcve]或chimes说要修复它.现在你在猜. (2认同)
  • FWIW我认为这是clang和gcc中的一个bug.将发布答案. (2认同)