可变参数模板的模板模板参数扩展 [英] template template parameter expansion for variadic templates

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

问题描述

我最近了解了模板模板参数的存在,现在想知道是否可能发生这样的事情:

I recently learned about the existence of template template parameters and was now wondering if something like this would be possible:

template<template<class... > class Container, typename... args>
struct ContainerTemplate
{
    using container = std::tuple<Container<args...>...>;
};

我想要的是一个模板,该模板将Container或其他模板类作为模板模板参数,然后以如果Container具有N个模板arg且我给出N * M个模板的方式扩展其余模板参数args的参数我得到N个模板args的M个模板实例,例如:

what i want is a template that gets a Container or some other template class as a template template parameter and then expands the rest of the template arguments in such a way that if Container has N template args and i give N * M template arguments for args i get M template instantiations with N template args eg:

ContainerTemplate<std::vector, int, short, char>
//assuming std::vector takes only 1 arg for simplicity    

应该导致

container = std::tuple<std::vector<int>, std::vector<short>, std::vector<char>>

同时

ContainerTemplate<std::map, int, int, short, short>
//assuming std::map takes only 2 args for simplicity    

应该导致

container = std::tuple<std::map<int, int>, std::map<short, short>>

有没有办法做到这一点?问题是您是否可以找出容器需要多少个模板参数.

Is there any way to do this? The question would be wether you could find out how many template args Container takes or not.

如果要求您以大小为N的元组传递附加参数,那就没问题了

it would be ok if you were required to pass the additional arguments in tuples of size N

ContainerTemplate<std::map, std::tuple<int, int>, std::tuple<short, short>>

Edit2:所以我实际上找到了一种确定模板模板参数数量的方法

so i actually found a way to determine the number of template template arguments

template<typename... T>
struct TypeList
{
    static const size_t Size = sizeof...(T);
    template<typename T2>
    struct PushFront
    {
        typedef TypeList<T2, T...> type_list;
    };
};

template<template<class...> class Template, typename... Args>
struct SizeofTemplateTemplate
{
    static const size_t Size = 0;
    typedef TypeList<> type;
};

template<template<class...> class Template, typename Arg, typename... Args>
struct SizeofTemplateTemplate<Template, Arg, Args...>
{
    template<typename... Args>
    struct Test;

    typedef char yes[1];
    typedef char no[2];

    template<typename... Args>
    struct Test<TypeList<Args...>>
    {
        template<template<class...> class Template>
        static yes& TestTemplate(Template<Args...>* arg);

        template<template<class...> class Template>
        static no& TestTemplate(...);
    };


    typedef typename SizeofTemplateTemplate<Template, Args...>::type::PushFront<Arg>::type_list type;
    static const size_t Size = sizeof(Test<type>::TestTemplate<Template>(0)) == sizeof(yes) ? type::Size : SizeofTemplateTemplate<Template, Args...>::Size;
};

使用此代码,下面的代码将打印2

with this, the following code will print 2

std::cout << SizeofTemplateTemplate<std::vector, int, std::allocator<int>, int, int>::Size << std::endl;

我现在唯一的问题是dyp的解决方案使Visual Studio编译器xD崩溃

only problem i have now is that dyp's solution crashes the visual studio compiler xD

Edit3:此处的原始问题的完整解决方案: https://stackoverflow.com/a/22302867/1366591

complete solution for the original question here: https://stackoverflow.com/a/22302867/1366591

推荐答案

根据您的初次尝试是不可能的,但根据您的编辑是有可能的,其中参数打包在 std :: tuple 的.在这种情况下,下面的模板 Embed 在每个 tuple 中接受参数,并将其嵌入到 Container 中.

It is not possible according to your first attempt, but it is possible according to your edit, where arguments are packed within std::tuple's. In this case, template Embed below takes arguments in each tuple and embeds them in Container.

请参见在线示例.

template<template<class... > class Container, typename P>
struct Embed_t;

template<template<class... > class Container, typename... T>
struct Embed_t <Container, std::tuple <T...> >
{
    using type = Container <T...>;
};

template<template<class... > class Container, typename P>
using Embed = typename Embed_t <Container, P>::type;

template<template<class... > class Container, typename... P>
struct ContainerTemplate
{
    using container = std::tuple<Embed <Container, P>...>;
};

通常,将 ... 放在 ... 内非常棘手,并且只能在有限的情况下发生(我仅以一种有用的方式对此进行了管理).

In general, placing ... within ... is very tricky and can happen only in limited circumstances (I've only managed this once in a useful way).

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

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