Question

J'expérimentais avec C ++ 0x variadique modèles quand je suis tombé sur cette question:

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 me donne une erreur lorsque je tente de typedef le pack paramètres modèle.

En fait, je voudrais « stocker » les paramètres emballent dans un typedef, sans le déballer. C'est possible? Sinon, est-il une raison pour laquelle ce n'est pas autorisé?

Était-ce utile?

La solution

Une autre approche, qui est légèrement plus générique que Ben, se présente comme suit:

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

Autres conseils

Je pense que la raison pour laquelle il n'a pas le droit est qu'il serait en désordre, et vous pouvez travailler autour d'elle. Vous devez utiliser l'inversion de dépendance et de faire la struct stocker le pack de paramètres dans un modèle d'usine en mesure d'appliquer ce pack de paramètre à un autre modèle.

Quelque chose le long des lignes de:

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;

Je l'ai trouvé l'idée de Ben Voigt très utile dans mes propres efforts. Je l'ai modifié légèrement pour le rendre général pas seulement tuples. Pour les lecteurs ici, il est peut-être une modification évidente, mais il peut être intéressant montrer:

template <template <class ... Args> class T, class ... Args>
struct TypeWithList
{
  typedef T<Args...> type;
};

template <template <class ... Args> class T, class ... Args>
struct TypeWithList<T, VariadicTypedef<Args...>>
{
  typedef typename TypeWithList<T, Args...>::type type;
};

Le TypeWithList nom provient du fait que le type est maintenant instancié avec une liste précédente.

Ceci est une variante de truc de spécialisation partielle nette de GManNickG. Aucune délégation, et vous obtenez plus de sécurité de type en exigeant l'utilisation de votre struct variadic_typedef.

#include <tuple>

template<typename... Args>
struct variadic_typedef {};

template<typename... Args>
struct convert_in_tuple {
    //Leaving this empty will cause the compiler
    //to complain if you try to access a "type" member.
    //You may also be able to do something like:
    //static_assert(std::is_same<>::value, "blah")
    //if you know something about the types.
};

template<typename... Args>
struct convert_in_tuple< variadic_typedef<Args...> > {
    //use Args normally
    typedef std::tuple<Args...> type;
};

typedef variadic_typedef<int, float> myTypes;
typedef convert_in_tuple<myTypes>::type int_float_tuple; //compiles
//typedef convert_in_tuple<int, float>::type int_float_tuple; //doesn't compile

int main() {}
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top