在模板模板参数 - 模板绑定中抛出多模板类? [英] Throw multiple-template class in a template template parameter - template binding?

查看:150
本文介绍了在模板模板参数 - 模板绑定中抛出多模板类?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

给定以下类:

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

我现在可以这样编写代码:

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

什么是最优雅的方式放置多参数类的所有参数指定除了一个,在B?像一个带有int键的地图?我唯一可以想出的是这样:

 模板< class U&使用C = MyMap< int,U> ;; 
A< float,C< int>> a3;

是否有这样的模板等同于std :: bind,我们可以只提供一部分参数并让其中一个打开?我相信这种语言没有提供这个,但人们必须在此之前解决这个问题。

  A< float ,MyMap< int,_>> α3; 


解决方案

std :: bind ,但你可以自己写一个。这里有一个简单的版本,它绑定了第一个模板参数,您可以根据需要扩展它:

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

然后你只需使用 bind_t1

  A< float,bind_t1< int,std :: map& a3; 

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

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






这是一个稍微扩展的版本,

 模板< template< typename ...>类B,类型名... Ts> 
struct bind_nt1 {
template< typename ... Us>
using type = B< Ts ...,Us ...> ;;
};

//用法
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 ...>类B,类型名... 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 ...>
};


//用法
A

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


Given the following class:

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

I can now write code like such:

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

What is the most elegant way to put multi-parameter classes of which all parameters are specified except one, in B? Like a map with int-keys? The only thing I can come up with is this:

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

Is there such a template equivalent to std::bind, where we can provide only a part of the parameters and leave one of them open? I'm quite sure the language doesn't provide for this, but people must've solved this before.

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

解决方案

There isn't a built-in template equivalent to std::bind, but you can write one yourself. Here's a simple version which binds the first template argument which you could extend to suit your needs:

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

Then you just use bind_t1 like so:

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

Note that for your example, you'll need to modify your template parameters to take a variadic template template:

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


Here's a slightly extended version which can bind a number of contiguous elements at the start of the parameter list:

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;


Here's a generic version based on the way std::bind does things. It doesn't do any validation and probably has some edge cases, but it's a good starting point. Thanks to Piotr Skotnicki for improvements.

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;

Using this, you can even change the order of template parameters:

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

这篇关于在模板模板参数 - 模板绑定中抛出多模板类?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆