Неоднозначное выражение доступа к члену: отклоняет ли Clang действительный код?

У меня есть код, который для целей этого вопроса сводится к

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();
}
23
задан curiousguy 10 December 2011 в 03:50
поделиться