2013-07-15 4 views
0

Я пытаюсь заменить виртуальные функции шаблонов:Заменить виртуальные функции шаблонов

struct Derived1; 
struct Derived2; 

template <typename T> 
struct Base 
{ 
    void f(); 
}; 

template<> 
void Base::f<Derived1>(){std::cout<<"Derived1\n";} 

template<> 
void Base::f<Derived2>(){std::cout<<"Derived2\n";} 


struct Derived1 : public Base {}; 
struct Derived2 : public Base {}; 

Он работает, пока мы не создадим контейнер указателей:

std::vector<Base*> vec;//doesn't work - needs explicit parameter for Base 
vec.push_back(new Derived1); 
vec[0]->f();//Call f() from Derived1 

Можно ли избавиться от «виртуальность» в этом случае?

+1

Взгляните на CRTP. Я только когда-либо видел это немного иначе. – chris

+2

Там вообще нет ключевого слова 'virtual'. Специализация шаблона не похожа на «виртуальную». Вопрос очень неясен, потому что вы просите получить * rid * от виртуальности, но в первую очередь нет. – Potatoswatter

+1

'Base :: f()' специализация тоже не выглядит правильно. Функция-член 'Base :: f' не является функцией шаблона, но ваше определение специализируется на' Base :: f ', что не имеет никакого смысла. Вы пробовали компилировать этот код? – greatwolf

ответ

2

virtual Функция отправки может определять динамический тип объекта выполнения, прежде чем выбирать, какую функцию вызывать. Шаблоны не могут этого сделать, потому что все они разрешены во время компиляции. Если у вас есть base *, ни один шаблон не поможет вспомнить, какой производный тип был инициализирован.

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

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