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