[英]Template function broken after compiling with C++11
我有一个非常简单的模板函数来比较两个structs
的rank
字段:
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.