Рассмотрим следующий фрагмент:
#include <iostream>
template <int I>
constexpr int f() { return I * f<I-1>(); }
template<>
constexpr int f<0>() { return 1; }int main () {
std::cout << f<5>();
return 0;
}
Этот код прекрасно компилируется как с g ++, так и clang. Очень хорошо.
Теперь добавьте static
к специализации функции шаблона:
template<>
constexpr static int f<0>() { return 1; }
тогда g ++ 6.1 реагирует с ошибкой:
11: ошибка: явная специализация шаблона не может иметь класс хранения
и лязг 3.8 тоже:
11: ошибка: явная специализация имеет посторонний, несовместимый класс хранения «статический»
Они выглядят как в согласии. Очень приятно снова.
Теперь добавьте static
Ключевое слово также шаблон функции общего случая:
g ++ 6.1:
11: ошибка: явная специализация шаблона не может иметь класс хранения
clang 3.8 компилируется с предупреждением:
11: предупреждение: явная специализация не может иметь класс хранения
и результат лягушки возвращает правильный ответ.
Это ошибка в Clang? Если нет, то в каком случае имеет смысл не выдавать ошибку?
Это так же просто, как [Dcl.stc] / 1 (который восходит к C ++ 98):
хранения класса спецификатор Кроме как
thread_local
не должно указываться в явной специализации (14.7.3) или в явной директиве (14.7.2).
Других решений пока нет …