将一个模板包装在另一个模板中

Wrapping a template in another template

我有一对 class 模板声明,如下所示:

template<typename T, template<typename W> class X>
struct B {
    bool operator()(const T& left, const T& right)
    { return X<W>()(left, right); }
};

template<template<typename T> class X, typename Q>
struct A {
   bool operator()(const int a, const int b)
   {
      return B<Q, X>()(a, b);
   }
};

我可以创建 A<std::greater, int>A<std::less, int> 并且它可以按我的意愿工作。

是否可以创建一个 class 来包含像 std::greater 一样传入的模板,并且仍然能够像上面示例中的 std::greater 本身一样被传递?

像这样:

template <template <typename T> class Class>
class Wrapper
{
   operator()(const int, const int) { return Class<?what's here?> (value, value); }
};

我想把我的 Wrapper 传给一个不变的 A

A<Wrapper<std::less>, long>

换句话说,我想模仿传递给我包装器的模板,以与 class A.

的实际版本兼容

简短的回答是否定的,不太像你想要的那样。 A 的第一个参数必须是模板名称。但是当你添加参数并写成 Wrapper<std::less> 时,你会得到一个 class 类型。它不再是模板。可以这样想,A 需要一个饼干切割器,但你却传递了一个用切割器制成的饼干。

这并不是说您不能将一个模板变成另一个模板,但它不会那么不透明。解决方案是在 Wrapper 中添加一个 member 模板。然后 Wrapper<std::less>,尽管是 class 类型,但会有一个模板成员。您可以将其传递给 A.

template <template <typename T> class Class>
struct Wrapper
{
   template<typename U> // member template
   struct temp {
     bool operator()(const int v1, const int v2)
     { return Class<U>()(v1, v2); }
   };
};

这使您可以编写 A<Wrapper<std::less>::temp, long>

看看live