Когда создаются шаблоны классов?

Предположим, что у вас есть следующая (некорректная) программа:

struct A
{
    A(int, int)
    {
    }
};

template <typename T>
class B
{
    B()
    {
        if (sizeof (T) == 1)
        {
            throw A(0); // wrong, A() needs two arguments
        }
    }
};

int main()
{
    return 0;
}

GCC компилирует эту программу без каких-либо ошибок, clang++ отказывается от нее с ошибкой.

  • Можно ли сказать, что это не ошибка в GCC, потому что шаблон не создан?
  • Какую магию делает clang, чтобы найти эту ошибку?
  • Что говорит об этом в стандарте С++?

Ответ 1

Шаблон создается при его использовании. Однако он должен быть скомпилирован, когда он будет определен. В вашем коде A(0) используется имя A, которое не зависит от параметра шаблона T, поэтому оно должно быть разрешено при определении шаблона. Это называется двухфазным поиском. То, как clang находит ошибку, просто пытается решить вызов A(0), как только он его увидит.

Моя версия GCC также незаметно компилирует этот код, даже с -pedantic-errors. Как С++ 03, так и С++ 11 говорят, что диагностика не требуется, хотя программа плохо сформирована, поэтому GCC соответствует. Это 14.6/7 в С++ 03 и 14.6/8 в С++ 11:

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

Ответ 2

  • Да. Если не существует действительной специализации, но шаблон не создается, как здесь - программа плохо сформирована, но диагностика не требуется (14.6/8). Таким образом, как clang, так и g++ являются правильными.

  • clang делает больше проверок, чем g++ в объявлении шаблона.

  • См. выше.