此模板解析冲突称为什么?

时间:2018-12-05 19:08:23

标签: 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;
}

实际的错误信息还不足以显示:

|| 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’

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

此错误有名字吗?

此外,我通过交换比较以使用>来解决了该问题。有更好的方法吗?

1 个答案:

答案 0 :(得分:7)

T.C. pointed out的主题是CWG active issue 1835

  

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

     
    

在类成员访问表达式(8.2.5 [expr.ref])中,如果。或->令牌后紧跟一个标识符,后跟一个<,必须查询该标识符以确定<是否为     模板参数列表的开头(17.2 [temp.names])或     小于运算符。首先在的类中查找标识符     对象表达式。如果找不到标识符,则为     在整个后缀表达式的上下文中查找并应     为课程模板命名。

  
     

给予

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

由于它是依赖的,因此无法在   对象表达式,它是在   后缀表达式。此查找找到功能模板,使   该表达式格式错误。

     

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

一种解决方法是使用()

return (sp->conflict) < 0;

see it live on godbolt