2014-10-18 4 views
1

Я не понимаю, почему следующее не удается:шаблона частичной специализации не будет работать

#include <cassert> 
#include <memory> 
#include <utility> 

using namespace std; 

template<typename... T> struct name{ static const char* value; }; 

template<typename... T> const char* name<T...>::value = "unknown"; 
template <> const char* name<int>::value = "int"; 
template <> const char* name<float>::value = "float"; 
template <> const char* name<template<typename,typename> class T>::value = "pair"; 

int main() 
{ 
    assert(name<int>::value == "int"); 
    assert(name<float>::value == "float"); 
    assert(name<double>::value == "unknown"); 
    assert((name<pair<int, char> >::value) == "pair"); 
} 

проблема находится в линии

template <> const char* name<template<typename,typename> class T>::value = "pair"; 

[temp.class.spec.mfunc] следует определите это поведение, но, прочитав стандарт, я все еще не понимаю его. Может ли кто-нибудь объяснить мне (самым ясным и лаконичным образом), почему никто из них не работает?

template <> const char* name<template<typename,typename> class T>::value = "pair"; 
template <typename T1, typename T2> const char* name<std::pair<T1,T2>>::value = "pair"; 
+0

http://stackoverflow.com/questions/26440493/template-class-specialization-with-template кажется, то же назначение, вы можете быть заинтересованы в ответах там – Mat

+0

I не понял этот ответ в первую очередь – Dean

+0

1. Вы не можете частично специализировать членов класса, 2. вы используете недействительный синтаксис для частичной специализации для шаблонов классов с двумя параметрами –

ответ

1

Вы можете частично специализировать шаблон класса, но вы не можете частично специализировать элемент шаблона класса. И это именно то, что вы пытаетесь сделать с вещью pair.

Почему preceisely попытка не работает:

template <> const char* name<template<typename,typename> class T>::value = "pair"; 

Явная специализация (то есть, не частичная специализация) не является шаблон. Он имеет префикс template <>, и у полностью специализированного имени шаблона должны быть аргументы, заданные для всех параметров шаблона. Таким образом, вы могли бы сделать, например, так:

template <> const char* name<std::pair<int, double>>::value = "pair"; 

Но исходный код синтаксическим нонсенс - если что-то, похоже, пытаюсь объявить шаблон двухпараметрического класса T внутри список аргументов шаблона.

Что касается второй линии:

template <typename T1, typename T2> const char* name<std::pair<T1,T2>>::value = "pair"; 

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

template <typename T1, typename T2> struct name<std::pair<T1,T2>> 
{ 
    static const char* value; 
}; 

template <typename T1, typename T2> const char* name<std::pair<T1,T2>>::value = "pair"; 
+0

Спасибо, это довольно хорошее объяснение. – Dean

Смежные вопросы