我试图通过破解代码Cracking the Code访谈(第81页)来解决以下练习:
动物收容所只饲养狗和猫,严格操作 "先进先出"基础。人们必须采用最老的" (基于到达时间)所有动物在收容所,或他们可以 选择他们是喜欢狗还是猫(并且会接受 这种类型的最古老的动物)。他们无法选择哪种特定的动物 他们想要。创建数据结构以维护此系统 并实现诸如enqueue,dequeueAny,dequeueDog和 dequeueCat。您可以使用内置的LinkedList数据结构。
只有两只动物很容易,我设法实施了一个类别的避难所,它保留两个独立的队列,一个用于猫和狗,并存储动物入队的时间。但是,我想知道如何将它推广到通用数量的动物,而不需要实际更改类Shelter的接口。我认为可变参数模板可以提供帮助,但我无法理解如何编写代码/语法来为不同类型的动物声明不同的队列。
首先这可能吗?有没有人有想法?
感谢您的建议,我认为我取得了一些进展:
template <typename A>
struct Animal {
string hello(void) {return A::hello(); }
string name;
};
class GenericAnimal {
public:
virtual string hello(void) {return "????";}
};
class Dog : public GenericAnimal {
public:
virtual string hello (void) {return "waf waf";}
};
class Cat : public GenericAnimal {
public:
virtual string hello (void) {return "miao miao";}
};
template <typename ...A>
class Shelter {
public:
Shelter():time(0){}
template <typename T>
void getQueueFor( queue< tuple<int, Animal<T>> > &q ){
q= get< queue< tuple<int, Animal<T>> > > (shelterQueues);
}
template <typename T>
void addAnimals(Animal<T> &a) {
tuple<int, Animal<T>> aa (time++, a);
(get< queue< tuple<int, Animal<T>> > > (shelterQueues)).push(aa);
}
GenericAnimal& getOldestAnimal (void) {
size_t size= std::tuple_size<decltype(shelterQueues)>::value;
for(size_t i=0; i < size; i++) {
get<0>(shelterQueues);
cout << i << ",";
}
cout << endl;
}
private:
int time;
tuple< queue< tuple <int, Animal<A>> >... > shelterQueues;
};
我现在可以把猫和狗吃掉。 现在,我试图实现dequeAny(),它应该返回系统中最老的动物,但是我被困住了。基本上,问题是我必须迭代队列的元组,看看哪个头的时间最短。环顾四周,我发现如何迭代元组iterate-over-tuple。问题是,即使我设法识别它,让我们称它为K,然后我需要做get(myQueue),这不应该工作,因为K在编译时是不知道的。我错了吗? 任何想法是否可能以及如何做到这一点?
由于
答案 0 :(得分:0)
使用std::tuple
。正如评论中所提到的,tuple<queue<T>>
适合您的用例。有关元组的一个有用的事情是,它允许您按类型查询元素,只要它模板化的类型是唯一的。这是一个例子:
template <typename ... Animals>
class AnimalQueue
{
public:
template <typename T>
queue<T> GetQueueFor(){return get<queue<T>>(mQueues);}
tuple<queue<Animals>...> mQueues;
};