сначала: я прочитал и теперь знаю, что функция-член виртуального шаблона невозможна (пока?) В C ++. Обходной путь должен был бы сделать класс шаблоном и затем использовать аргумент шаблона также в функции-члене.
Но в контексте ООП я обнаружил, что приведенный ниже пример не был бы очень "естественным", если бы класс был на самом деле шаблоном. Обратите внимание, что код на самом деле не работает, но gcc-4.3.4 сообщает: error: templates may not be ‘virtual’
#include <iostream>
#include <vector>
class Animal {
public:
template< class AMOUNT >
virtual void eat( AMOUNT amount ) const {
std::cout << "I eat like a generic Animal." << std::endl;
}
virtual ~Animal() {
}
};
class Wolf : public Animal {
public:
template< class AMOUNT >
void eat( AMOUNT amount) const {
std::cout << "I eat like a wolf!" << std::endl;
}
virtual ~Wolf() {
}
};
class Fish : public Animal {
public:
template< class AMOUNT >
void eat( AMOUNT amount) const {
std::cout << "I eat like a fish!" << std::endl;
}
virtual ~Fish() {
}
};
class GoldFish : public Fish {
public:
template< class AMOUNT >
void eat( AMOUNT amount) const {
std::cout << "I eat like a goldfish!" << std::endl;
}
virtual ~GoldFish() {
}
};
class OtherAnimal : public Animal {
virtual ~OtherAnimal() {
}
};
int main() {
std::vector<Animal*> animals;
animals.push_back(new Animal());
animals.push_back(new Wolf());
animals.push_back(new Fish());
animals.push_back(new GoldFish());
animals.push_back(new OtherAnimal());
for (std::vector<Animal*>::const_iterator it = animals.begin(); it != animals.end(); ++it) {
(*it)->eat();
delete *it;
}
return 0;
}
Так что создание "Fish foo" довольно странно. Тем не менее, мне кажется желательным обеспечить произвольное количество пищи для каждого животного.
Таким образом, я ищу решение о том, как достичь чего-то вроде
Fish bar;
bar.eat( SomeAmount food );
Это становится особенно полезным, если смотреть на цикл for. Можно хотеть кормить определенное количество (FoodAmount) всем различным животным (например, через eat () и bind1st ()), это не может быть сделано так легко, хотя я нахожу это очень интуитивным (и, следовательно, в некоторой степени «естественно». Хотя некоторые, возможно, захотят поспорить, что это связано с «единообразным» характером вектора, я думаю / хочу, чтобы это было возможно, и мне бы очень хотелось узнать, как это происходит, поскольку озадачивает меня довольно долго ...
[EDIT]
Чтобы, возможно, прояснить мотивы, лежащие в основе моего вопроса, я хочу запрограммировать класс Exporter, и пусть другие, более специализированные классы будут происходить из него. В то время как класс Exporter верхнего уровня, как правило, предназначен только для косметических / структурных целей, класс GraphExporter является производным, который должен снова служить базовым классом для еще более специализированного экспорта. Однако, как и в примере с Animal, я хотел бы иметь возможность определять GraphExporter * даже в специализированных / производных классах (например, в SpecialGraphExplorer), но при вызове «write (out_file)» вместо этого он должен вызывать соответствующую функцию-член для SpecialGraphExporter GraphExporter :: write (out_file).
Может быть, это прояснит мою ситуацию и намерения.
Best
Shadow