我想实现一个泛型类型元素的容器;我希望这个容器支持比较器。
当使用STL的优先级队列时,我可以定义一个比较器并初始化我的优先级队列容器实例,如下所示:
bool IsMyItemLarger(MyItem* a, MyItem* b) {
if(a && b && a->value > b->value)
return true;
return false;
}
std::priority_queue<
MyItem*,
vector<MyItem*>,
std::function<bool(MyItem*, MyItem*)>
> pq(IsMyItemLarger);
现在,我想定义自己的容器类,我希望它支持包括基本类型在内的任何类型,因此模板T应该在类定义中。
template<typename T...>
class MyContainer {
public:
vector<T*> items;
};
但是,如何在容器类中定义比较器存根? (以便客户端可以传递例如&#34; bool(MyItem *,MyItem *)&#34;作为模板参数和&#34; IsMyItemLarger&#34;作为构造函数的参数?)
注意:(关于以下主题的内容!!)
我知道如何通过接口实现SIMILAR类,例如
我定义了一个接口,只有符合此接口的项才能插入到容器中。它可以通过编译(以下代码)
class AbstractBaseItem {
public:
virtual int compareTo(AbstractBaseItem* a) = 0;
};
class MyContainer {
public:
vector<AbstractBaseItem*> items;
bool greater(int i, int j) {
return items[i]->compareTo(items[j]) > 0;
}
};
class MyItem : public AbstractBaseItem {
public:
int value;
int compareTo(AbstractBaseItem* a) {
int aValue = ((MyItem*)a)->value;
if(value > aValue)
return 1;
else if(value < aValue)
return -1;
else
return 0;
}
};
但是,从逻辑上讲,我不想使用虚拟功能。容器中的所有项目应该是完全相同的类型,而不是&#34; as-is&#34;类型。例如。我只是希望MyItem在容器中,而不是MyItem,YourItem,HisItem等,尽管这些类都继承自AbstractBaseItem。它可能是一个原始类型,如int,long,double ......
所以模板实际上就是我想要的。
答案 0 :(得分:2)
比较被委托给另一个模板类型,为方便起见,通常会默认为std::greater<T>
,它完全按照它的样子行事;它已经在标准库中提供,还有许多其他操作,如less
,greater_equal
等,因此无需重写它们。它们被称为运算符包装器,可用于
<functional>
。
因此,
template<typename T, typename Compare>
// ^^^^^^^^^^^^^^^^
class MyContainer {
vector<T*> items;
/* public: */Compare compare;
// ...
{
if ( compare(T1, T2) )
}
};
Compare
的签名必须是
template <class T> bool cmp(const T&, const T&);
或类似的,以保持标准设计,其中cmp(a, b)
应该是一个有效的表达式;当然,你的可能会有所不同。有关它的更多信息here。
容器通常允许您使用他们收到的比较器对象,因此您可能也希望将其设为public
。
提示,如果我可以:
vector<T>
:指针不好;如果你必须使用它们,请选择智能指针。std::function
,只需要一个可调用的对象(普通函数,lambda ecc。)