ключевое слово "template" не нужно?[gcc / clang / Comeau bug?] - PullRequest
10 голосов
/ 24 января 2012

Вот код теста

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. Спасибо

П.С .: Я значительно отредактировал свой вопрос. Пожалуйста, не возражайте.

РЕДАКТИРОВАТЬ : Я задал этот вопрос людям EDG, и это то, что Майк Херрик сказал

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

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

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

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

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;

Ответы [ 2 ]

8 голосов
/ 25 января 2012

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

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

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

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

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

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

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

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

2 голосов
/ 24 января 2012

Я могу ошибаться, но я думаю, что это ошибка в 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 без каких-либо дополнительных доказательств. Я вернусь после еще нескольких стандартных погружений.

...