有没有办法绑定模板<template>参数?

Sha*_*ane 8 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();
    }
};
Run Code Online (Sandbox Code Playgroud)

我有一个接受比较器的第二类,例如:

template <template <typename> class Comparator>
class Processor { ... };
Run Code Online (Sandbox Code Playgroud)

Processor使用标准比较器(例如std::less)可以很容易地实例化:

Processor<std::less> processor1;
Processor<std::greater> processor2;
Run Code Online (Sandbox Code Playgroud)

然而,实例化并不是那么容易,SoftOrder因为编译器正确地抱怨缺少第二个模板参数:

Processor<SoftOrder<std::less> > processor3; // <-- Fails to compile
Run Code Online (Sandbox Code Playgroud)

当前解决方案

在发布此问题之前,我已经提出了一些解决方案.

第一个解决方案 - 大量派生类

template <typename T>
struct SoftOrderLessThan : public SoftOrder<std::less, T> {};

template <typename T>
struct SoftOrderGreaterThan : public SoftOrder<std::greater, T> {};
Run Code Online (Sandbox Code Playgroud)

此解决方案的主要缺点是每次需要新变量时都需要创建新结构,例如:

template <typename T>
struct SoftOrderLessThan : public SoftOrder<std::less, T> {}; // Never used after the next line.
Processor<SoftOrderLessThan> processor3;
Run Code Online (Sandbox Code Playgroud)

第二个解决方案 - 非常特定的绑定类

template <template <typename> class Comparator>
struct BindToSoftOrder {
    template <typename T>
    struct type : public SoftOrder<Comparator, T> {};
};
Run Code Online (Sandbox Code Playgroud)

这稍微好一些,因为我们不需要显式创建中间类:

Processor<BindToSoftOrder<std::less>::type> processor3;
Run Code Online (Sandbox Code Playgroud)

缺点是需要一个专门针对这种情况的类,这个类不能通过SoftOrder打开模板参数来实现,BindToSoftOrder因为这会使template<template<template>>>标准不允许.

第三个解决方案 - C++ 11模板别名

template <typename T>
using SoftOrderLessThan = SoftOrder<std::less, T>;
Run Code Online (Sandbox Code Playgroud)

比第一个选项更好,因为它不需要引入新类,但是仍然需要使用这个额外的代码乱丢代码,这些代码仅用于传递给另一个模板类:

template <typename T>
using SoftOrderLessThan = SoftOrder<std::less, T>; // Never used again
Processor<SoftOrderLessThan> processor3;
Run Code Online (Sandbox Code Playgroud)

最后,问题

是否有通用方法将我的自定义比较器以下列方式绑定到特定比较器?

Processor<SomeCoolMetaTemplateBind<SoftOrder, std::less>::type> processor3;
Run Code Online (Sandbox Code Playgroud)

我相信如果所有模板参数都是简单类型我可以做类似的事情Processor<boost::mpl::bind<SoftOrder, std::less> >,但模板参数列表中存在模板类型可以防止这种情况发生.

一个理想的解决方案将涉及C++ 03,但我也很高兴听到C++ 11解决方案.

如果不可能,我希望至少这个问题很有意思.

Vau*_*ato 3

看起来这会起作用:

template <
  template <template <typename> class,class> class U,
  template <typename> class X
>
struct SomeCoolMetaTemplateBind {
  template <typename T>
  struct type : public U<X,T> {
  };
};
Run Code Online (Sandbox Code Playgroud)