繁体   English   中英

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

[英]Template function broken after compiling with C++11

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

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

这很好用,直到用-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;
                       ^

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

编辑 :我在这里向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);
}

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

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

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

你的问题是你使用

using namespace std;

因为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;

无论如何, using namespace ...都不是一个好主意。 你给了一个很好的例子;)

这是CGW 1835处理的一个问题,请点击此处:

根据6.4.5 [basic.lookup.classref]段落

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

 template<typename T> T end(T); template<typename T> bool Foo(T it) { return it->end < it->end; } 

因为它是依赖的,因此无法在对象表达式的类中查找end,所以在postfix-expression的上下文中查找它。 此查找查找函数模板,使表达式格式错误。

一种可能性是在对象表达式依赖时将查找限制为对象表达式的类。


#include <type_traits>

using namespace std;

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

即使没有实例化函数模板,错误也会显示,整个表达式都是依赖的,因此它们无法查找到类范围。 由于标准的当前措辞不清楚,如果类别范围中的rank查找将推迟依赖名称,或者必须绑定到后缀表达式上下文中的名称,这是CGW试图解决的问题。

直接解决方案是使用parens:

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM