Подтвердить что ты не робот

Некоторые ошибки в неизведанном шаблоне, не сообщаемые g++

Рассмотрим следующий пример:

class A
{
  void foo();
  public:
  void bar();
};

template <class> class B
{
  B()
  {
    A a;
    a.foo();    // 1
    A::bar();   // 2
    a.bar(1);   // 3
  }
};

Примечание B никогда не создается.

clang++ сообщает все три маркированные строки как ошибочные. g++ (4.8.3) принимает строки 1 и 2 и только сообщает строку 3.

Если B создается, g++ с радостью сообщает о всех трех строках как ошибочные.

Является ли это ошибкой g++? Можно так думать. A не является зависимым именем, и его члены должны нормально проверяться во время определения шаблона. Есть ли нюансы, которые я не вижу?

4b9b3361

Ответ 1

Эти сообщения с предварительным экземпляром не применяются стандартом и соответствуют компилятору

n3337 § 14.6 - 8

Никакая диагностика не должна выдаваться для определения шаблона, для которого может быть создана действительная специализация. Если действительная специализация не может генерируется для определения шаблона, и этот шаблон не является экземпляр, определение шаблона плохо сформировано, нет диагностики требуется.

акцент мой

Ответ 2

В общем случае невозможно определить, являются ли ошибки a.foo(); или A::bar(); ошибкой во время определения шаблона даже для тех конкретных определений A::foo и A::bar.

Вообще говоря, a.foo(); может быть действительным, если A имел некоторые специализации B<T> как друга, но не другие, что сделало бы действительность зависящей от аргумента шаблона.

Вообще говоря, A::bar(); может быть справедливым, если B<T> имел A как базовый класс, прямо или косвенно, а классы шаблонов обычно не знают свой базовый класс еще во время определения шаблона.

Несмотря на то, что можно обнаружить, что ни одно из них здесь не возможно (A не имеет друзей, а B<T> не имеет базы), это требует значительных усилий для небольшой выгоды. Из-за этого имеет смысл просто всегда выполнять такие проверки во время создания экземпляра и что подход GCC был принят.

На С++ на самом деле нет правила, которое требует, чтобы это было диагностировано во время определения шаблона (как справедливо указывает Марко А.). Это только при создании экземпляра шаблона, что любые ошибки в определении шаблона делают программу плохо сформированной с требованием для диагностики в точке 2.2p1 bullet 8:

Программа плохо сформирована, если какой-либо экземпляр не выполняется.

В вашей программе нет инстанцирования, поэтому нет экземпляра, который терпит неудачу.