我正在编写一个模板化的 C++ 通用容器类,它可以选择以定义明确的顺序维护其内容。以前它使用函数指针以一种合理的特定于类型的方式对其内容进行排序,但我正在尝试将其更改为使用模板仿函数参数。
由于通常情况下,类的用户可能希望在不同的容器中以不同的方式对相同类型的项目进行排序,因此容器类采用可选的模板参数,让用户可以选择指定自己的比较仿函数:
template <class ItemType, class CompareFunctorType = CompareFunctor<ItemType> > class MyContainer
{
[...]
};
如果类用户没有指定自定义仿函数类型,则默认使用以下 CompareFunctor 定义:
template <typename ItemType> class CompareFunctor
{
public:
bool IsItemLessThan(const ItemType & a, const ItemType & b) const
{
return (a<b); // will compile only for types with < operator
}
};
这对于内置类型和定义了小于运算符的用户定义类型非常有用。但是,我希望它也自动适用于没有内置或明确定义小于运算符的类型。对于这些类型,容器内项目的顺序并不重要。
动机是我用这个容器来容纳很多不同的类型,而且大多数时候,我不关心容器中类型的顺序,但在某些情况下我关心......和我不想进入并向所有这些不同类型添加“虚拟”小于运算符,这样我就可以将它们与这个容器类一起使用……而且我不想必须明确指定一个每次我使用表存储没有小于运算符的项目时自定义“虚拟”CompareFunctor 参数。
那么,有没有一种方法可以使用模板特化(或其他方法),以便尽可能使用默认的 CompareFunctor(如上所示),但在 CompareFunctor 会导致错误的情况下,C++ 会自动回退到“dummy”FallbackCompareFunctor 像下面的那个吗?或者也许还有其他聪明的方法来处理这个难题?
template <typename ItemType> class FallbackCompareFunctor
{
public:
bool IsItemLessThan(const ItemType & a, const ItemType & b) const
{
return ((&a)<(&b)); // will compile for all types (useful for types where the ordering is not important)
}
};
最佳答案
对于默认未排序的情况,使用一个 Null 比较仿函数,它对所有情况都返回 false。
然后,您可以使用 std::less() 仿函数将您的模板专门化为排序容器。
template<class T>
struct NullCompare: public binary_function <T, T, bool>
{
bool operator()(const T &l, const T &r) const
{
// edit: previously had "return true;" which is wrong.
return false;
}
};
template <class T, class Compare=NullCompare<T> >
class MyContainer
{
[...]
};
template <class T, class Compare=std::less<T> >
class MySortedContainer : public MyContainer<T, Compare>
{
[...]
};
关于C++ 模板化容器类 : How to best support both ordered and un-ordered item types?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1183448/