c++ - 有没有办法绑定(bind) template<template> 参数?

标签 c++ templates boost boost-mpl

上下文

我有一个自定义比较器,它采用另一个比较器并应用额外的检查:

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/

相关文章:

函数参数中的c++函数定义

c++ - 接收通用 map 作为参数的模板函数

c++ - 为什么 SFINAE 技巧在尝试类成员指针时不适用于非类类型?

c++ - 从特定顶点执行深度优先算法

c++ - Debug模式下的 xcode 链接器错误(重复符号)

c++ - BOOST ASIO - 如何编写控制台服务器

C++ 设计 : Overloading/Overriding many many functions, 的清理方式?

C++模板相互依赖类型

c++ - 强制 cpp_dec_float 向下舍入

c++ - 字符串 "figured"显示为 "?gured"