【问题标题】:Throw multiple-template class in a template template parameter - template binding?在模板模板参数中抛出多个模板类 - 模板绑定?
【发布时间】:2015-09-04 10:24:02
【问题描述】:

给定以下类:

template <class T, template <typename> class B>
class A { B<T> b; };

我现在可以编写如下代码:

A<float, MyVector> a1;
A<int, MySet> a2;

将除一个以外的所有参数都指定的多参数类放在 B 中的最优雅的方法是什么?像带有 int 键的地图?我唯一能想到的是:

template <class U> using C = MyMap<int, U>;
A<float, C<int>> a3;

有没有这样一个模板相当于std::bind,我们可以只提供一部分参数而让其中一个保持打开状态?我很确定该语言没有提供此功能,但人们以前一定已经解决了这个问题。

A<float, MyMap<int, _>> a3;

【问题讨论】:

  • 请注意std::vector&lt;T, Allocator&gt;template &lt;typename&gt; class B不直接兼容。
  • 啊,是的,我的错;我会更新帖子以反映。

标签: c++ templates template-templates


【解决方案1】:

没有等效于std::bind 的内置模板,但您可以自己编写一个。这是一个简单的版本,它绑定了您可以扩展以满足您的需要的第一个模板参数:

template <typename T, template <typename...> class B>
struct bind_t1 {
    template <typename... Ts>
    using type = B<T,Ts...>;   
};

那么你只需像这样使用bind_t1

A<float, bind_t1<int, std::map>::type> a3;

请注意,对于您的示例,您需要修改模板参数以采用可变参数模板模板:

template <class T, template <typename...> class B>
class A { B<T> b; };

这是一个稍微扩展的版本,它可以在参数列表的开头绑定许多连续的元素:

template <template <typename...> class B, typename... Ts>
struct bind_nt1 {
    template <typename... Us>
    using type = B<Ts...,Us...>;   
};

//Usage
A<std::less<int>, bind_nt1<std::map, int, float>::type> a3;

这是基于std::bind 做事方式的通用版本。它不做任何验证,可能有一些边缘情况,但这是一个很好的起点。感谢Piotr Skotnicki 的改进。

template <std::size_t N> 
struct placeholder{};

template <template <typename...> class B, typename... Ts>
struct bind_t {
private:
    template <typename T, typename UTuple>
    struct resolve_placeholder {
        using type = T;
    };

    template <std::size_t N, typename UTuple>
    struct resolve_placeholder<placeholder<N>, UTuple> {
        using type = typename std::tuple_element<N-1, UTuple>::type;
    };

public:
    template <typename... Us>
    using type = B<typename resolve_placeholder<Ts, std::tuple<Us...>>::type...>;
};


//Usage 
A<int, bind_t<std::map, float, placeholder<1>, std::less<float>>::type> a3;

使用这个,你甚至可以改变模板参数的顺序:

//std::map<int,float>
bind_t<std::map, placeholder<2>, placeholder<1>>::type<float, int> b;

【讨论】:

  • 通过元组和索引序列扩展Ts的参数包看起来是多余的
  • @PiotrSkotnicki 谢谢,已修复。
  • 我的意思是an even simpler solution
  • @PiotrSkotnicki 是的,这样更好。你想用它发布答案还是介意我只是编辑它?
  • @TartanLlama 不不,我不介意,这仍然是您的解决方案
猜你喜欢
  • 1970-01-01
  • 2014-01-29
  • 1970-01-01
  • 2019-11-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-08-25
  • 2011-05-10
相关资源
最近更新 更多