我有一些代码,就这个问题而言,归结为
template<typename T>
class TemplateClass : public T {
public:
void method() {}
template<typename U>
static void static_method(U u) { u.TemplateClass::method(); }
};
class EmptyClass {};
int main() {
TemplateClass<TemplateClass<EmptyClass> > c;
TemplateClass<EmptyClass>::static_method(c);
}
我试图用两个编译器的几个版本来编译它。GCC 4.2、4.4、4.6 毫无怨言地接受它。截至 11 月 14 日的 Clang 2.9 和 SVN 主干拒绝它,并显示以下错误消息:
example.cc:6:38: error: lookup of 'TemplateClass' in member access expression is
ambiguous
static void static_method(U u) { u.TemplateClass::method(); }
^
example.cc:13:3: note: in instantiation of function template specialization
'TemplateClass<EmptyClass>::static_method<TemplateClass<TemplateClass<EmptyClass>
> >' requested here
TemplateClass<EmptyClass>::static_method(c);
^
example.cc:2:7: note: lookup in the object type
'TemplateClass<TemplateClass<EmptyClass> >' refers here
class TemplateClass : public T {
^
example.cc:2:7: note: lookup from the current scope refers here
1 error generated.
哪一个是错的?我可以通过更改来解决 Clang
static void static_method(U u) { u.TemplateClass::method(); }
至
static void static_method(U u) { u.TemplateClass<T>::method(); }
但我想对何时可以省略模板参数的理解充满信心。
编辑:我曾认为歧义是在TemplateClass
. 以下代码使用 GCC 和 Clang 编译,质疑该假设:
class E {};
template<typename T>
class A : public T {
public:
void method() {}
};
int main() {
A<A<E> > a;
a.A::method();
}