Специализация статической переменной-члена класса шаблона при использовании также синтаксиса 'extern template class' - PullRequest
0 голосов
/ 01 февраля 2019

У меня есть шаблонный класс, который я собираюсь использовать только с 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'

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

Ответы [ 2 ]

0 голосов
/ 04 февраля 2019

Это действительно ошибка в компиляторе Microsoft, уже вошедшая в их бэклог.Следите за обновлениями: https://developercommunity.visualstudio.com/content/problem/319447/explicit-specialization-of-static-data-member-inco.html

0 голосов
/ 02 февраля 2019

MSVC здесь неверен: «проблемная» строка не является определением, поскольку она не имеет инициализатора .

Clang тем временем корректен, чтобы отклонить версию без этого объявления, поскольку явная реализацияобъявление также явное объявление экземпляра A<int>::x.

...