специализация шаблона и инициализация статических членов - PullRequest
0 голосов
/ 19 января 2019

Допустим, есть шаблонный класс:

template<typename T>
class Storage
{
public:
    static std::map<T, std::vector<std::string> > things;
};

А теперь я хочу специализировать его для типа int и инициализировать things.

Способ, который не выдает ошибки компиляции, которые я нашел до сих пор, таков:

template<>
std::map<int, std::vector<std::string> > Storage<int>::things = {
    { 1, {"FOO", "foo"} },
    { 2, {"BAR", "bar"} },
    { 3, {"ZAR", "zar"} }
};

Но как получается, что мы можем специализировать класс и инициализировать статический член одновременно?

1 Ответ

0 голосов
/ 19 января 2019

Код:

template<>
std::map<int, std::vector<std::string> > Storage<int>::things = {
    { 1, {"FOO", "foo"} },
    { 2, {"BAR", "bar"} },
    { 3, {"ZAR", "zar"} }
};

- это не специализация шаблона класса Storage, а специализация статического члена данных шаблона класса .

Элемент класса шаблона может быть специализированным (при условии, что нет нестатических элементов данных).То есть можно специализировать весь класс шаблона как единое целое, как в:

template<class T>
struct A{
   struct B{
      using type = T;
      };
    void g();
    };

 template<>
 struct A<void>{}; //specialize the entire class.

Или специализировать только элемент шаблона класса:

//Specialization of B for A<int>
template<>
struct A<int>::B{
   static int f();
   };

Приведенная выше специализация членаэквивалентно специализации класса шаблона:

template<>
struct A<int>{
   struct B{ //come from the member specialization definition
     static int f();
     };
   void g(); //come from unspecialized A definition.
   };

В результате вы можете наблюдать это, если попытаетесь скомпилировать:

A<char>::B::type x = `a`; 
A<double>::B::type y = `b`; 

A<int>::B::type err; //compilation error
int z = A<int>::B::f(); //ok.

A<void>::B o; //compilation error
auto w = A<void>::f(); //compilation error
...