这个模板解析冲突叫什么?
What is this template parsing conflict called?
我在使用 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
字段。
这个错误有名字吗?
此外,我通过将比较交换为使用 >
来修复它。有没有更好的方法?
如 this is the subject of CWG active issue 1835 表示:
According to 6.4.5 [basic.lookup.classref] paragraph 1,
In a class member access expression (8.2.5 [expr.ref]), if the . or -> token is immediately followed by an identifier followed by a <, the identifier must be looked up to determine whether the < is the
beginning of a template argument list (17.2 [temp.names]) or a
less-than operator. The identifier is first looked up in the class of
the object expression. If the identifier is not found, it is then
looked up in the context of the entire postfix-expression and shall
name a class template.
给出
template<typename T> T end(T);
template<typename T>
bool Foo(T it) {
return it->end < it->end;
}
因为它是依赖的,因此在 class 中无法查找 end
对象表达式,它在
后缀表达式。此查找找到函数模板,使
表达式不正确。
一种可能是将查找限制为 class
对象表达式依赖时的对象表达式。
解决方法是使用 ()
:
return (sp->conflict) < 0;
我在使用 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
字段。
这个错误有名字吗?
此外,我通过将比较交换为使用 >
来修复它。有没有更好的方法?
如
According to 6.4.5 [basic.lookup.classref] paragraph 1,
In a class member access expression (8.2.5 [expr.ref]), if the . or -> token is immediately followed by an identifier followed by a <, the identifier must be looked up to determine whether the < is the beginning of a template argument list (17.2 [temp.names]) or a less-than operator. The identifier is first looked up in the class of the object expression. If the identifier is not found, it is then looked up in the context of the entire postfix-expression and shall name a class template.
给出
template<typename T> T end(T); template<typename T> bool Foo(T it) { return it->end < it->end; }
因为它是依赖的,因此在 class 中无法查找 end 对象表达式,它在 后缀表达式。此查找找到函数模板,使 表达式不正确。
一种可能是将查找限制为 class 对象表达式依赖时的对象表达式。
解决方法是使用 ()
:
return (sp->conflict) < 0;