是否可以"存储"模板参数包而不扩展它?

Luc*_*lle 71 c++ templates variadic-templates c++11

当我偶然发现这个问题时,我正在尝试使用C++ 0x可变参数模板:

template < typename ...Args >
struct identities
{
    typedef Args type; //compile error: "parameter packs not expanded with '...'
};

//The following code just shows an example of potential use, but has no relation
//with what I am actually trying to achieve.
template < typename T >
struct convert_in_tuple
{
    typedef std::tuple< typename T::type... > type;
};

typedef convert_in_tuple< identities< int, float > >::type int_float_tuple;
Run Code Online (Sandbox Code Playgroud)

当我尝试输入模板参数包时,GCC 4.5.0给出了一个错误.

基本上,我想将参数包"存储"在typedef中,而无需解压缩.可能吗?如果没有,是否有一些理由不允许这样做?

GMa*_*ckG 56

另一种比Ben更通用的方法如下:

#include <tuple>

template <typename... Args>
struct variadic_typedef
{
    // this single type represents a collection of types,
    // as the template arguments it took to define it
};

template <typename... Args>
struct convert_in_tuple
{
    // base case, nothing special,
    // just use the arguments directly
    // however they need to be used
    typedef std::tuple<Args...> type;
};

template <typename... Args>
struct convert_in_tuple<variadic_typedef<Args...>>
{
    // expand the variadic_typedef back into
    // its arguments, via specialization
    // (doesn't rely on functionality to be provided
    // by the variadic_typedef struct itself, generic)
    typedef typename convert_in_tuple<Args...>::type type;
};

typedef variadic_typedef<int, float> myTypes;
typedef convert_in_tuple<myTypes>::type int_float_tuple;

int main()
{}
Run Code Online (Sandbox Code Playgroud)

  • 我有点担心:虽然说"处理类型列表,或者包含列表的特定类型的实例同样的东西"是非常诱人的,但根据我的经验,当你遇到麻烦时去做.例如,想象一个长度为1的列表,其中包含`variadic_typedef`以及它与上述代码的交互方式.现在想象一下每个类型的列表,每个类型都传递给`convert_in_tuple`以及它如何与上面的代码交互.如果您开始设置几个间接级别,将容器和内容视为可互换会导致问题. (3认同)
  • 我不明白这如何解决OP的问题。Convert_in_tuple 结构包含元组别名的别名。它表示的类型是带有 Args ... 参数包的元组,而不是 Args ... 参数包本身。 (2认同)

Ben*_*igt 9

我认为它不被允许的原因是它会很混乱,你可以解决它.您需要使用依赖项反转并将存储参数包的结构体转换为工厂模板,以便将该参数包应用于另一个模板.

有点像:

template < typename ...Args >
struct identities
{
    template < template<typename ...> class T >
    struct apply
    {
        typedef T<Args...> type;
    };
};

template < template<template<typename ...> class> class T >
struct convert_in_tuple
{
    typedef typename T<std::tuple>::type type;
};

typedef convert_in_tuple< identities< int, float >::apply >::type int_float_tuple;
Run Code Online (Sandbox Code Playgroud)