Я создал шаблон класса со статическим элементом const. Цель каждой специализации шаблона состоит в том, чтобы иметь свою собственную версию/значение этого статического элемента. Вот мой пример код:Инициализация статической константы для специализации шаблона
template < typename T > class C
{
public:
static const std::string NAME;
T something;
void printName() { std::cout << NAME << std::endl; }
};
class C1 : public C<int>{};
class C2 : public C<char>{};
template<> const std::string C<int>::NAME{ "my int" }; // compiles
template<> const std::string C<char>::NAME{ "my char" }; // compiles
//template<> const std::string C1::NAME{ "my int" }; // doesn't compile
//template<> const std::string C2::NAME{ "my char" }; // doesn't compile
//const std::string C1::NAME{ "my int" }; // doesn't compile
//const std::string C2::NAME{ "my char" }; // doesn't compile
int main()
{
C1 c1;
C2 c2;
c1.printName();
c2.printName();
std::cout << c1.NAME << " " << c2.NAME << std::endl;
std::cout << C1::NAME << " " << C2::NAME << std::endl;
}
При использовании компилируемых версий, вывод, что я бы ожидать:
my int
my char
my int my char
my int my char
Для линий, которые не компилируются, сообщение об ошибке (с помощью GCC 4.4) говорит
ISO C++ does not permit 'C<int>::NAME' to be defined as 'C1::NAME'
Почему это не разрешено? Я понимаю, что полная специализация шаблона - это класс во всех (?) Уважениях, и этот класс имеет все члены, объявленные в шаблоне. Поэтому я ожидаю, что смогу обратиться к статическим членам этого класса, используя оператор разрешения области. По-видимому, я могу сделать это после инициализации, как в последней строке, указанной выше, но не в самой инициализации.
Может ли кто-нибудь дать представление о том, почему стандарт был написан таким образом? Какие проблемы возникнут, если стандарт допустил синтаксис «bad» выше?
Это делает вещи более ясными. Я новичок в шаблонах и по-прежнему пытаюсь разобраться в таких концепциях, как создание экземпляров и специализация, и как объединить их с наследованием и т. Д. Давайте посмотрим, есть ли у меня это сейчас: способ, которым я объявил класс C1, компилятор будет генерировать (неявный) экземпляр C, который будет базовым классом для C1. Статический член принадлежит базовому классу, поэтому мне нужно использовать имя базового класса «C » для его инициализации. Аналогично для C2 & C . C и C не имеют отношения наследования; они просто генерируются из одного шаблона. Это верно? –
user3065699
Что касается ожидаемого, я хочу, чтобы C1 и C2 (а точнее, их соответствующие базовые классы) имели статический член с именем NAME с разными значениями для каждого (базового) класса. Вот что мне удалось в итоге; Я просто не совсем понял, как это работает. – user3065699