Похоже, что правила для экземпляра шаблона в Clang (3.8) и GNU C++ (4.9) не совпадают. Ниже приведен пример:Создание экземпляра шаблона в GNU C++ и Clang
#include <cstddef>
template <bool>
class Assert {
Assert(); // private constructor for Assert<false>
};
template <>
class Assert<true> { // implicit public constructor for Assert<true>
};
template <size_t N>
class A {
};
template <class T, size_t N>
T foo(A<N>) {
return T(N - 1);
}
template <class T>
T foo(A<0>) { // foo is not defined for N=0
Assert<false>();
return T(0);
}
int main(int argc, char **argv) {
foo<int>(A<3>());
return 0;
}
Этот минимальный пример показывает функцию шаблона, foo
, что обобщенно над типа T
и натурального числа N
. Эта функция не определена для N=0
, поэтому я хотел бы использовать класс Assert
, чтобы сигнализировать ошибку компилятора, если он используется таким образом.
Этот код принят компилятором GNU (и Visual C++ 2015, а также), но Clang дает сообщение об ошибке «вызов частного конструктора класса Assert<false>
».
Итак, кто прав? Как я вижу, нет вызова для foo<T,0>
, поэтому нет необходимости создавать экземпляр этого шаблона ...
EDIT: Принимая интерпретацию стандарта Clang стандартом, каков канонический способ принудительной проверки времени компиляции шаблона параметры?
Так что 'Assert' проверяется и проверяется, даже если 'foo ' никогда не был создан? Разве это не лишняя работа? В любом случае, учитывая, что он работает так, что является стандартным способом утверждения компилятора в параметре шаблона? (Я отредактировал вопрос соответствующим образом.) –
vukung
@vukung На самом деле это меньше работает, потому что компилятор должен искать 'Assert' один раз, когда шаблон определен, а не каждый раз, когда создается экземпляр шаблона. –
Oktalist
Зачем вам писать код, который никогда не будет использоваться? Это звучит как много дополнительной работы для ВАС. – xaxxon