Невозможно объявить переменную шаблона без ее определения

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

Я был убежден, что шаблоны переменных C ++ 14 работают так же, как статические переменные класса. К сожалению, похоже, что это не совсем так, и это мешает мне заранее объявить мои переменные шаблоны.

template <typename T> struct Variable {
static int variable;
};

template <typename T>
extern int variable;

int main() {
(void) Variable<char>::variable;
// (void) variable<char>;                   // <-- line 10
}

template <> int Variable<char>::variable = 42;
template <> int variable<char> = 23;

Пример кода выше компилируется и запускается как есть в GCC. Но раскомментирующая строка 10 выдает ошибку времени компиляции:

specialization of 'variable<char>' after instantiation
template <> int variable<char> = 23;
^

5

Решение

Я думаю, что вы на правильном пути.

Хитрость заключается в следующем: ни в одном из модулей перевода не создавайте экземпляр шаблона до того, как вы специализовались.

Например:

// test.h
#ifndef TEST_H
#define TEST_H

template <typename T>
extern int variable;

template <> extern int variable<char>;
template <> extern int variable<int>;

#endif // TEST_H

Затем:

// test2.cpp
#include "test.h"
template <> int variable<char> = 23;
template <> int variable<int> = 24;

И наконец:

// test.cpp
#include "test.h"#include <iostream>

int
main()
{
std::cout << variable<char> << '\n';
std::cout << variable<int> << '\n';
}

Для меня это выводы:

23
24

Обновить

Агар Т.С. В комментариях ниже указано, что специализации должны быть объявлены перед первым использованием, поэтому я обновил «test.h» выше, чтобы сделать это.

Обновление 2

Кажется, есть некоторые расхождения в реализации. Clang, кажется, справиться с этим штрафом:

template <typename T>
extern int variable;

template <> extern int variable<char>;
template <> extern int variable<int>;

#include <iostream>

int
main()
{
std::cout << variable<char> << '\n';
std::cout << variable<int> << '\n';
}

template <> int variable<char> = 23;
template <> int variable<int> = 24;

http://melpon.org/wandbox/permlink/DGYKvvoPbmRIHaFi

Однако gcc выдает ошибку:

prog.cc:4:13: error: explicit template specialization cannot have a storage class
template <> extern int variable<char>;
^~~~~~

prog.cc:5:13: error: explicit template specialization cannot have a storage class
template <> extern int variable<int>;
^~~~~~

Я искал стандарт и список основных проблем, и я не могу найти ничего, что указывало бы, что один компилятор или другой верны. Если кто-то увидит такие доказательства, я с радостью включу их в этот ответ.

1

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]