Ключевое слово "шаблон" не требуется? [gcc/clang/Ошибка комо?]

Вот тестовый код

template <class T> void f()
{
  T t;
  t.f<T>(0); //compiles even without the "template" keyword, what am I missing?
}

class abc
{
  public:
  template <typename T>
  void f (int){}
};

int main()
{
  f<abc>();
}

Я использую g++ 4.4.6. Благодаря

P.S: Я значительно изменил свой вопрос. Пожалуйста, не против.

EDIT: я задал этот вопрос людям EDG, и это то, что Майк Херрик должен был сказать

Мы диагностируем это как ошибку в режиме -strict, а также в любом режиме, который позволяет искать зависимые имена (например, --dep_name, --parse_templates). Зависимый поиск имени отключается в режимах эмуляции GNU, поэтому мы не испускаем эту ошибку в этом случае.

Обработка зависимых имен требует создания экземпляров прототипа nonclass (см. ниже). Как и при создании экземпляров прототипа nonclass, зависимый поиск имени, вероятно, вызовет ошибки компиляции при компиляции код, который не был написан с учетом этой функции.

В зависимых правилах поиска имен требуется, чтобы независимые имена были посмотрел на точку использования в определении шаблона, и что разрешение перегрузки должно выполняться на независящих вызовах в этой точке. Для зависимых вызовов набор рассмотренных имен является набором видимых в месте использования в определении шаблона плюс любые сделанные имена видимый зависящим от аргумента поиска в момент создания экземпляра. Обратите внимание: встроенные типы не имеют связанных пространств имен, поэтому вызовы только встроенные типы могут разрешать только имена, видимые в определение шаблона. Кроме того, имена из зависимых базовых классов не отображаются для неквалифицированных поисков.

Ниже приведены некоторые из наиболее распространенных проблем с кодом при поиске зависимого имени:

template <class T> struct B {
    void f();
  };

template <class T> struct A : public B<T> {
    X x;  // error: X not visible yet (formerly an error in strict mode)
    void g() {
      f();        // error: B<T>::f not visible
      this->f();  // must be written this way
      h(1);  // error: h(int) not visible using argument-dependent lookup
    }
  };
struct X {};
void h(int);
A<int> ai;

Ответ 1

Ключевое слово template требуется как из-за того, что t является зависимым именем, а потому, что f<T> является специализированной функцией шаблона зависимой функции-члена. Соответствующая спецификация разбросана по разделу 14, но начинается с §14.2/4 (как в С++ 03, так и в С++ 11).

Проблема связана с неправильным поиском имен: gcc находит шаблон функции пространства имен f в точке объявления, а затем в момент создания экземпляра разрешает f шаблон элемента-члена abc.

Если вы переименуете шаблон функции пространства имен или шаблон функции-члена, вы получите правильное поведение от компилятора.

Это давняя ошибка gcc:

Код с отсутствующим ключевым словом "шаблон" ошибочно принят

Странное столкновение с одинаковыми именами в разных областях

См. также много дубликатов ошибок, разрешенных для обоих из них. Я не вижу, чтобы ошибка Clang открывалась для этого.

Поиск имени из шаблона функции был указан в С++ 03; было обнаружено много дефектов по этому вопросу, и спецификация претерпела значительные изменения в С++ 11, чтобы уточнить детали и угловые случаи и устранить тонкие проблемы.

Ответ 2

Я мог ошибаться, но я думаю, что это ошибка в GCC. Рассмотрим следующий случай:

template <class T> bool f() {T t = {2}; return t.f < 4;}

struct abc { int f; };

int main() { f<abc>(); }

Я ожидал бы, что компилировать просто отлично, но GCC (и Clang) предполагают, что t.f называет функцию шаблона и ожидает закрытия >. Соответствующей частью стандарта является §14.2/4.

Тем не менее, я немного нерешительно заявляю, что такая ошибка может существовать как в Clang, так и в GCC без каких-либо дополнительных доказательств. Я вернусь после еще нескольких стандартных погружений.