gpt4 book ai didi

c++ - 虚拟模板设计

转载 作者:行者123 更新时间:2023-11-28 06:04:02 26 4
gpt4 key购买 nike

为了使用一个简化的示例,让我们考虑一些动物正在吃食物列表中的某些项目。食物列表针对不同的情况有很多不同的迭代器。

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 中描述的迭代器列表)。

最佳答案

你可以重新组织你的界面,这样每个 Animal 都被虚拟地喂食一个 Food 和一系列非虚拟的 Food:

class Animal
{
public:
virtual ~Animal() {}
virtual void eat(Food& ) = 0; // or Food const&

template <typename Iterator>
void eat(Iterator begin, Iterator end) {
for (; begin != end; ++begin) {
eat(*begin);
}
}
};

虽然如果你真的需要整个范围,你可以使用类似 boost::any_range 的东西:

class Animal
{
public:
using FoodRange = boost::any_range<Food, boost::forward_traversal_tag,
Food&, std::ptrdiff_t>;

virtual ~Animal() {}
virtual void eat(FoodRange ) = 0;

template <typename Iterator>
void eat(Iterator begin, Iterator end) {
eat(FoodRange{begin, end});
}
};

关于c++ - 虚拟模板设计,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32744494/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com