У меня есть код, который для целей этого вопроса сводится к
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 принимают его без жалобы. Clang 2.9 и SVN с 14 ноября отклоняют его со следующим сообщением об ошибке:
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(); }
но я хотел бы быть уверенным в своем понимании, когда он ОК, чтобы исключить параметры шаблона.
EDIT: Я думал, что двусмысленность была между двумя экземплярами TemplateClass
. Следующий код компилируется с GCC и Clang, что вызывает сомнения в этой гипотезе:
class E {};
template<typename T>
class A : public T {
public:
void method() {}
};
int main() {
A<A<E> > a;
a.A::method();
}