爲了使用簡化的示例,讓我們考慮一些動物在食物列表中吃一些食物。食物列表針對不同的情況有很多不同的迭代器。虛擬模板設計
class contains_fish
{
public:
bool operator() (const Food& food) const;
};
class is_vegetarian
{
public:
bool operator() (const Food& food) const;
};
class FoodList
{
private:
std::vector<Food> foodItems;
public:
typedef std::vector<Food>::iterator iterator;
typedef std::vector<Food>::const_iterator const_iterator;
typedef std::vector<Food>::reverse_iterator reverse_iterator;
typedef std::vector<Food>::const_reverse_iterator const_reverse_iterator;
typedef boost::filter_iterator<contains_fish,FoodList::iterator> fish_iterator;
typedef boost::filter_iterator<contains_fish,FoodList::const_iterator> fish_const_iterator;
typedef boost::filter_iterator<contains_fish,FoodList::reverse_iterator> fish_reverse_iterator;
typedef boost::filter_iterator<contains_fish,FoodList::const_reverse_iterator> fish_const_reverse_iterator;
typedef boost::filter_iterator<is_vegetarian,FoodList::iterator> vegetarian_iterator;
typedef boost::filter_iterator<is_vegetarian,FoodList::const_iterator> vegetarian_const_iterator;
typedef boost::filter_iterator<is_vegetarian,FoodList::reverse_iterator> vegetarian_reverse_iterator;
typedef boost::filter_iterator<is_vegetarian,FoodList::const_reverse_iterator> vegetarian_const_reverse_iterator;
//...
//... with corresponding begin/end functions :
FoodList::iterator begin() { return this->foodItems.begin(); }
FoodList::const_iterator begin() const { return this->foodItems.begin(); }
//...
FoodList::vegetarian_const_reverse_iterator begin_vegetarian_const_reverse() const { return boost::make_filter_iterator<is_vegetarian>(this->foodItems.rbegin(), this->foodItems.rend()); }
};
現在我想給食物列表上的迭代器給每個動物食物(一個虛函數)。這樣的代碼的東西(不工作,由於虛擬模板功能):
class Animal
{
public:
virtual ~Animal() {}
template <typename FoodListIterator>
virtual void eat(FoodListIterator begin, FoodListIterator end) = 0;
};
class Dog : public Animal
{
public:
virtual ~Dog() {}
template <typename FoodListIterator>
virtual void eat(FoodListIterator begin, FoodListIterator end)
{
if(begin == end)
std::cout << "Sad day ! Nothing for me..." << std::endl;
else
{
std::cout << "I'm a dog and I'm going to eat :" << std::endl;
for(FoodListIterator it = begin; it != end; ++it)
std::cout << it->toString() << std::endl;
}
}
};
void give_fish(std::vector<Animal*>& animals, const FoodList& food_list)
{
for(unsigned long int i = 0; i < animals.size(); ++i)
animals[i]->eat(food_list.fish_begin(), food_list.fish_end());
}
我有太多不同的迭代器來實現每個簽名的虛函數。
如何在不使用C++ 11的情況下優雅地做到這一點?如果它可以幫助,我知道類型的列表(在FoodList中描述的迭代器列表)。
由於您已經在使用Boost,因此您應該可以使用Boost的['any_range']( http://www.boost.org/doc/libs/1_59_0/libs/range/doc/html/range/reference/ranges/any_range.html)或者只是其隨附的'any_iterator'。 – Angew
作爲一般規則,不要將編譯時多態性(模板)與運行時多態性(虛擬調用)混合使用。他們在一起打球不好。 – SergeyA
@Angew:如果我很好理解這個工具,我可以使用'boost :: range_detail :: any_iterator'而不是我的模板類型'FoodListIterator'?但我不明白我必須使用什麼作爲第二個模板類型...: -/ –
Caduchon