如何curry可变参数模板模板参数? [英] How can I curry variadic template template parameters?

查看:183
本文介绍了如何curry可变参数模板模板参数?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

Variadic模板模板参数接受任何模板:

Variadic template template parameters accept any template:

template<typename T>
struct Test1 {
    using type = int;
};

template<typename T, typename T1>
struct Test2 {
    using type = char*;
};

template<template<typename...S> class BeCurry>
struct Currying {
};

using curry  = Currying<Test1>;
using curry2 = Currying<Test2>;

我想要Currying模板模板类。

这意味着:一个模板参数为 Test1 curry :: apply< T> :: type get Test1< T> :: type 。如果参数接受两个模板参数为 Test2 curry2 :: apply< T0> curry2 :: apply< T0> :: apply< T1> :: type get Test2< T0,T1> :: type

I want Currying template template class.
It means: if the parameter accepts one template param as Test1, curry::apply<T>::type get Test1<T>::type. If the paramter accepts two template params as Test2, curry2::apply<T0> is a 'Partial' template, curry2::apply<T0>::apply<T1>::type get Test2<T0,T1>::type

这是否可以实现?因为我不能查询模板模板参数的内部参数num:

Is this possible to implement? Because I can't query inner parameter num of template template parameters:

template<template<typename... S> class BeCurry>
struct Currying {
    enum { value = sizeof...(S) }; // error!
};


推荐答案

简单的解决方案是:

template
    <
        template <typename...> class BeCurry,
        typename... Params
    >
struct Currying
{
    template <typename... OtherParams>
    using curried = BeCurry<Params..., OtherParams...>;

    template <typename... OtherParams>
    using type = typename curried<OtherParams...>::type;

    template <typename... NewParams>
    using apply = Currying<curried, NewParams...>;
};

但它不适用于 Test1 Test2 由于编译错误(至少在 gcc 下)。此问题的解决方法如下所示:

But it does not work with templates like Test1 and Test2 due to compilation errors (under gcc, at least). A workaround for this problem looks like this:

template
    <
        template <typename...> class BeCurry,
        typename... Params
    >
struct Curry
{
    using type = BeCurry<Params...>;
};

template
    <
        template <typename...> class BeCurry
    >
struct Curry<BeCurry>
{
    using type = BeCurry<>;
};

现在行

template <typename... OtherParams>
using curried = BeCurry<Params..., OtherParams...>;

应替换为

template <typename... OtherParams>
using curried = typename Curry<BeCurry, Params..., OtherParams...>::type;

使用示例:

#include <iostream>
#include <typeinfo>

template <typename T>
void print_type(T t)
{
    std::cout << typeid(t).name() << std::endl;
}

// ...

print_type(Currying<Test1>::type<int>{});
print_type(Currying<Test1>::apply<int>::type<>{});
print_type(Currying<Test2>::type<int, char>{});
print_type(Currying<Test2>::apply<int>::type<char>{});
print_type(Currying<Test2>::apply<int>::apply<char>::type<>{});
print_type(Currying<Test2>::apply<int, char>::type<>{});

ideone

这篇关于如何curry可变参数模板模板参数?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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