У меня есть шаблонный класс, который я собираюсь использовать только с 3 различными типами, которые я знаю заранее.Чтобы уменьшить раздувание кода, я хочу сохранить как можно больше за пределами заголовка.Класс шаблона также имеет статические переменные, которые должны различаться в зависимости от специализации.
Я пытался добиться этого как в Windows с Visual C ++ 19.15.26729, так и на Mac с XCode и clang-900.0.39.2.Мне нужен был другой код, чтобы удовлетворить каждый из компиляторов, и что еще хуже, компиляторы жаловались на «хорошие» версии программы друг друга.
Вот минимальный пример:
// A.h
template<typename T>
class A
{
public:
static T x;
};
// template<> int A<int>::x; // PROBLEMATIC PART
extern template class A<int>;
// A.cpp
#include "A.h"
template<> int A<int>::x = 42;
template class A<int>;
// main.cpp
#include "A.h"
int main()
{
return A<int>::x;
}
Приведенный выше код (с прокомментированной строкой) прекрасно компилируется на VC ++, но clang жалуется: Explicit specialization of 'x' after instantiation
Ответ на этот вопрос помог: Какой правильный способ специализировать шаблон прииспользуя "внешний шаблон"?
С template<> int A<int>::x;
без комментариев он прекрасно компилируется в Xcode, но затем Visual C ++ жалуется:
1>A.cpp(3): error C2086: 'T A<int>::x': redefinition
1> with
1> [
1> T=int
1> ]
1>A.h(9): note: see declaration of 'x'
1>A.cpp(3): error C2086: 'T A<T>::x': redefinition
1> with
1> [
1> T=int
1> ]
1>A.h(6): note: see declaration of 'A<int>::x'
Мой подход в корне неверен?Это ошибка компилятора?Может быть, это функция, поддерживаемая только одним из компиляторов, если так - какая версия верна в соответствии со стандартом?