为了使用简化的例子,让我们考虑一些动物在食物清单中吃一些食物。食物清单在不同的情况下有很多不同的迭代器。
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中描述的迭代器列表)。
答案 0 :(得分:1)
您可以重新组织界面,以便每个<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent"
android:layout_height="match_parent" android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
android:paddingBottom="@dimen/activity_vertical_margin"
android:fillViewport="true"
tools:context="com.cecode.www.gjcode.MainTypes"
android:animateLayoutChanges="true">
<LinearLayout
android:layout_width="match_parent"
android:orientation="vertical"
android:gravity="center"
android:layout_height="match_parent">
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Options Menu(placeholder)"
android:id="@+id/optionsBtn"
/>
<Button
android:layout_width="400dp"
android:layout_height="80dp"
android:text="Top Text"
android:id="@+id/button1"
android:layout_marginTop="110dp"
/>
<Button
android:layout_width="400dp"
android:layout_height="80dp"
android:text="placeholder text"
android:id="@+id/button2"
android:layout_marginTop="20dp"
/>
<Button
android:layout_width="400dp"
android:layout_height="80dp"
android:text="placeholder text"
android:id="@+id/button3"
android:layout_marginTop="20dp"
/>
<Button
android:layout_width="400dp"
android:layout_height="80dp"
android:text="placeholder text"
android:id="@+id/button4"
android:layout_marginTop="20dp"
/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceLarge"
android:text="mid text"
android:id="@+id/textView3"
/>
<LinearLayout android:layout_width="match_parent"
android:layout_height="wrap_content"
android:minHeight="50dp"
android:orientation="vertical">
<!-- add your button here -->
</LinearLayout>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceLarge"
android:text="bottom text"
android:id="@+id/textView4"
/>
</LinearLayout>
</ScrollView>
虚拟地提供一个Animal
,并且非虚拟地提供一系列Food
:
Food
虽然如果你真的需要整个范围,你可以使用类似boost::any_range
的东西:
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);
}
}
};