首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何修改各种模板模板参数?

问如何修改各种模板模板参数?
EN

Stack Overflow用户
提问于 2014-01-28 13:22:13
回答 2查看 1.1K关注 0票数 9

可变模板模板参数接受任何模板:

代码语言:javascript
复制
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>;

我想要运行模板模板类。

它的意思是:如果参数接受一个模板param作为Test1,则为curry::apply<T>::type get Test1<T>::type。如果参数接受两个模板参数作为Test2,则curry2::apply<T0>是“部分”模板,curry2::apply<T0>::apply<T1>::type get Test2<T0,T1>::type

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

代码语言:javascript
复制
template<template<typename... S> class BeCurry>
struct Currying {
    enum { value = sizeof...(S) }; // error!
};
EN

回答 2

Stack Overflow用户

发布于 2014-01-29 10:48:06

简单的解决办法是:

代码语言:javascript
复制
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...>;
};

但由于编译错误(至少在gcc的领导下),它不适用于像Test1和Test2这样的模板。解决此问题的方法如下所示:

代码语言:javascript
复制
template
    <
        template <typename...> class BeCurry,
        typename... Params
    >
struct Curry
{
    using type = BeCurry<Params...>;
};

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

现在行了

代码语言:javascript
复制
template <typename... OtherParams>
using curried = BeCurry<Params..., OtherParams...>;

应该用线代替

代码语言:javascript
复制
template <typename... OtherParams>
using curried = typename Curry<BeCurry, Params..., OtherParams...>::type;

使用示例:

代码语言:javascript
复制
#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<>{});

意为的完整示例。

票数 3
EN

Stack Overflow用户

发布于 2014-01-29 20:47:59

在我自己的一些问题之后,我想出了这个解决方案,它适用于任何模板类(也是您在文章中提供的)。

该解决方案的核心是is_valid_specialization,它用作是否认为当前过程可以被认为是完整的条件。

代码语言:javascript
复制
#include <iostream>
#include <type_traits>

template<template<typename...> class C, typename... T>
struct is_valid_specialization {
    typedef struct { char _; } yes;
    typedef struct { yes _[2]; } no;

    template<template<typename...> class D>
    static yes test(D<T...>*);
    template<template<typename...> class D>
    static no test(...);

    constexpr static bool value = (sizeof(test<C>(0)) == sizeof(yes));
};

namespace detail {

    template<template<typename...> class BeCurry, bool = false, typename... S>
    struct Currying {

        template<typename... T>
        using apply = Currying<BeCurry, is_valid_specialization<BeCurry, S..., T...>::value, S..., T...>;
    };

    template<template<typename...> class BeCurry, typename... S>
    struct Currying<BeCurry, true, S...> {

        template<typename... T>
        using apply = Currying<BeCurry, is_valid_specialization<BeCurry, S..., T...>::value, S..., T...>;

        using type = typename BeCurry<S...>::type;
    };
}

template<template<typename...> class BeCurry>
using Currying = detail::Currying<BeCurry, is_valid_specialization<BeCurry>::value>;

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

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

template<typename...>
struct Test3 { using type = double; };

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

template<typename T>
void pretty_print(T) {
    std::cout << __PRETTY_FUNCTION__ << std::endl;
}

int main() {
    pretty_print(typename curry::apply<char>::type{});
    pretty_print(typename curry2::apply<int>::apply<char>::type{});
    pretty_print(typename curry3::type{});
}

意为上的输出

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/21406726

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档