2011-01-14 81 views
68

我用的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; 

GCC 4.5.0给我一个错误,当我尝试的typedef模板参数包。

基本上,我想将参数包“存储”在typedef中,而不用解包它。可能吗?如果不是,有什么理由不允许这样做?

回答

50

另一种方法,这是稍微比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() 
{} 
8

我认为这是不允许的原因是它会很混乱,你可以解决它。您需要使用依赖关系反转,并将存储参数包的结构放入工厂模板中,以便将该参数包应用于其他模板。

东西线沿线的:

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; 
+0

我在GCC 4.5上试过了你的代码,你只需要在`class T`中改变`typename T`并将`convert_in_tuple`参数改为template template模板参数:`template