2011-01-14 3 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; 

私はテンプレートパラメータパックをtypedefをしようとすると、GCC 4.5.0は私にエラーを与えます。

基本的には、パラメータパックをアンパックせずにtypedefに「格納」したいと思います。出来ますか?そうでない場合は、これが許可されていない理由がいくつかありますか?

答えて

50

もう少し一般的なベンのより別のアプローチは、次のとおりです。

#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() 
{} 
+0

ニースは、OPが最初に試したものに非常によく似ています。 –

+1

非常に良い回避策、私は部分的なテンプレートの専門化を使用することについて考えなかった! –

+0

@GMan:簡単な質問...これは役に立ちましたが、部分的に特殊化されたバージョンは実際に 'typedef typename convert_in_tuple :: type type;'であるべきですか、それとも関係ありませんか? – Jason

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