这个模板解析冲突叫什么?

Nat*_*ate 9 c++ templates name-lookup

我正在用g ++ 7.3编译这个最小的例子

template<typename T>
struct conflict
{
};

template<typename T>
struct s
{
    int conflict;
};

template<typename T>
bool go()
{
    s<T>* sp;
    return sp->conflict < 0;
}
Run Code Online (Sandbox Code Playgroud)

实际的错误消息不足以揭示:

|| test.cpp: In function ‘bool go()’:
test.cpp|16 col 24| error: type/value mismatch at argument 1 in template parameter list for ‘template<class T> struct conflict’
||   return sp->conflict < 0;
||                         ^
test.cpp|16 col 24| note:   expected a type, got ‘0’
Run Code Online (Sandbox Code Playgroud)

实际上,编译器正在尝试实例化conflict模板而不是比较conflict字段.

这个错误有名字吗?

另外,我通过交换比较来修复它>.有没有更好的办法?

Sha*_*our 7

正如TC所指出的,这是CWG活跃问题1835的主题,其中说:

根据6.4.5 [basic.lookup.classref]第1段,

在类成员访问表达式(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;
   }
Run Code Online (Sandbox Code Playgroud)

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

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

修复是使用():

return (sp->conflict) < 0;
Run Code Online (Sandbox Code Playgroud)

看到它生活在godbolt上