我有一个自定义比较器,需要另一个比较器并应用额外的检查:
template <template <typename> class Comparator, typename T>
struct SoftOrder : public std::binary_function<T, T, bool> {
bool operator()(const T lhs, const T rhs) const {
return Comparator<T>()(lhs, rhs) && AnotherCheck();
}
};
我有第二个接受比较器的类,例如:
template <template <typename> class Comparator>
class Processor { ... };
使用标准比较器(例如Processor
)很容易实例化std::less
,如下所示:
Processor<std::less> processor1;
Processor<std::greater> processor2;
然而,使用SoftOrder
进行实例化并不是那么容易,因为编译器正确地抱怨缺少第二个模板参数:
Processor<SoftOrder<std::less> > processor3; // <-- Fails to compile
在发布此问题之前,我已经提出了一些解决方案。
template <typename T>
struct SoftOrderLessThan : public SoftOrder<std::less, T> {};
template <typename T>
struct SoftOrderGreaterThan : public SoftOrder<std::greater, T> {};
此解决方案的主要缺点是每次需要新变体时都需要创建一个新结构,例如:
template <typename T>
struct SoftOrderLessThan : public SoftOrder<std::less, T> {}; // Never used after the next line.
Processor<SoftOrderLessThan> processor3;
template <template <typename> class Comparator>
struct BindToSoftOrder {
template <typename T>
struct type : public SoftOrder<Comparator, T> {};
};
这稍微好一点,因为我们不需要明确地创建中间类:
Processor<BindToSoftOrder<std::less>::type> processor3;
缺点是需要一个专门针对这种情况的类,这种情况无法通过在SoftOrder
上设置BindToSoftOrder
模板参数来实现,因为这会使template<template<template>>>
成为template <typename T>
using SoftOrderLessThan = SoftOrder<std::less, T>;
标准允许。
template <typename T>
using SoftOrderLessThan = SoftOrder<std::less, T>; // Never used again
Processor<SoftOrderLessThan> processor3;
比第一个选项更好,因为它不需要引入新类,但是仍然需要使用这些额外的代码乱丢代码,这些代码仅用于传递给另一个模板类:
Processor<SomeCoolMetaTemplateBind<SoftOrder, std::less>::type> processor3;
是否有以下方式将自定义比较器绑定到特定比较器的通用方法?
Processor<boost::mpl::bind<SoftOrder, std::less> >
我相信如果所有模板参数都是简单类型,我可以像{{1}}这样做,但模板参数列表中存在模板类型可以防止这种情况发生。
理想的解决方案将涉及C ++ 03,但我也很高兴听到C ++ 11解决方案。
如果不可能,我希望至少这个问题很有意思。
答案 0 :(得分:1)
似乎这样可行:
template <
template <template <typename> class,class> class U,
template <typename> class X
>
struct SomeCoolMetaTemplateBind {
template <typename T>
struct type : public U<X,T> {
};
};