2015-06-12 4 views
0

Недавно я начал изучать C++. И я иногда путаюсь с типовой специализацией. Может ли кто-нибудь сказать мне причину, почему следующая типовая специализация в № (3) является незаконной?шаблон специализации с параметром шаблона

template<typename T> // No (1) 
class ClassA { 
public: 
    ClassA(); 
    virtual ~ClassA(); 

    void func(void); 
}; 

template<> // No (2) 
void ClassA<int>::func(void) {} // Ok legal specialization 

template<typename T> // No (3) 
void ClassA<int>::func(void) {} // error by compiler 

Кажется, специализация шаблона в No (3) не имеет неявного параметра шаблона, потому что typename T является int. Но компилятор дает следующее сообщение об ошибке,

error: prototype for ‘void ClassA<int>::func()’ does not match any in class ‘ClassA<int>’ void ClassA<int>::func(void) { 
         ^

error: candidate is: void ClassA<T>::func() [with T = int] void func(void); 
         ^

Я боюсь, я задаю глупый вопрос, но я действительно хочу знать причину ошибки. И я удивляюсь, что typename Ts у No 1 и No3 такие же или нет. Пожалуйста, скажите мне их. Большое спасибо.

+1

ни (2), ни (3) не должны компилироваться – bolov

+0

В C++ вы обычно пишете 'func()', а не 'func (void)'. Более поздняя версия разрешена только для обратной совместимости с C. –

ответ

0

Вместо

template<typename T> 
void ClassA<int>::func(void) {} 

Использование

template<typename T> 
void ClassA<T>::func(void) {} 
     // ^^^ T, not it. 

Я не уверен, было ли использование int нарочно или это упущение.

+0

. Их вопрос заключается в объявлении '' специализации их шаблона, а не общего определения шаблона. – CoryKramer

+0

Привет и думаю, что вы отвечаете на него, coryKramer. Это было специально. Я проиндексировал параметр шаблона в No (1) как int, но я также намеренно помещал typemame T в No (3), потому что я предполагал, что T at No (3) выводится на int. – mora

2

(2) - способ написать специализацию.

T в (1) и (3) не являются на самом деле то же самое, вы можете написать (для не специализации):

template <typename U> 
void ClassA<U>::func(void) {} 

тогда как это было в (1)

или частичному специализируются T

template <typename T> 
void ClassA<std::vector<T>>::func(void) {} 

где здесь T1 в (1) будет std::vector<T3>.

+0

спасибо, Jarod42. Это то, что я хотел знать. Но если это так, мне интересно, почему мы не можем писать только void ClassA :: func (void) {} ​​в шаблоне <> void ClassA :: func (void) {}? Я чувствую, что первый шаблон <> меня смутил. – mora

+0

Я думаю, что это должен иметь единственный синтаксис и когерентный синтаксис (с аргументом N или даже 0 шаблона). Также обратите внимание, что грамматика должна управлять методом шаблона для шаблона (шаблон шаблона void A :: foo (U) ') и явное инстанцирование (' template class A ; '). – Jarod42

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