上下文
我有一个自定义比较器,它采用另一个比较器并应用额外的检查:
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;
第二种解决方案 - 一个非常具体的绑定(bind)类
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>>>
这是标准不允许的。
第三种解决方案——C++11模板别名
template <typename T>
using SoftOrderLessThan = SoftOrder<std::less, T>;
比第一个选项更好,因为它不需要引入新类,但是仍然需要在代码中添加仅用于传递给另一个模板类的额外代码:
template <typename T>
using SoftOrderLessThan = SoftOrder<std::less, T>; // Never used again
Processor<SoftOrderLessThan> processor3;
最后是问题
是否有一种通用方法可以按照以下方式将我的自定义比较器绑定(bind)到特定比较器?
Processor<SomeCoolMetaTemplateBind<SoftOrder, std::less>::type> processor3;
我相信如果所有的模板参数都是简单类型,我可以做类似 Processor<boost::mpl::bind<SoftOrder, std::less> >
的事情。 , 但模板参数列表中模板类型的存在阻止了这种情况的发生。
理想的解决方案将涉及 C++03,但我也很高兴听到 C++11 解决方案。
如果不可能,我希望至少这个问题很有趣。
最佳答案
似乎这样可行:
template <
template <template <typename> class,class> class U,
template <typename> class X
>
struct SomeCoolMetaTemplateBind {
template <typename T>
struct type : public U<X,T> {
};
};
关于c++ - 有没有办法绑定(bind) template<template> 参数?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11377290/