7 votes

Mélange de types et de non-types dans les paramètres de modèles variadiques ?

Est-il possible de mélanger les types et les non-types dans les paramètres de modèles variadiques ? Si je passe un std::array par exemple à cette classe comme paramètre T je devrais également passer un type pour le tableau et une longueur, mais la façon dont j'ai essayé ci-dessous provoque une erreur lorsque je rencontre une valeur, parce qu'elle n'attend que les types pour Types :

template <
    template<class, std::size_t>  class T,
    class ... Types>
class C {

    T<Types...> storage;
};

int main(){
    C<std::array, int, 3> c;
}

Message d'erreur :

error: template argument for template type parameter must be a
      type
    Container<std::array, int, 3> c;
                               ^

Existe-t-il un moyen de transmettre des types et des valeurs dans un contexte variadique ?

4voto

Barry Points 45207

Est-il possible de mélanger les types et les non-types dans les paramètres de modèles variadiques ?

Non. Vous ne pouvez pas mélanger les deux. Mais comme vous pouvez envelopper une valeur dans un type mais pas l'inverse, vous pouvez rester dans le monde des types :

template <template<class...> class T, class ... Types>
class C {    
    T<Types...> storage;
};

Et ensuite, il s'agit juste de faire std::array ne fonctionnent qu'avec des types :

template <class T, class N>
using my_array = std::array<T, N::value>;

template <size_t N>
using size_ = std::integral_constant<size_t, N>;

Donc votre exemple original devient :

C<my_array, int, size_<3>> c;

2voto

Guillaume Racicot Points 1106

Comme je le vois, vous avez déjà codé en dur le nombre et les types de paramètres de la classe. T doit prendre comme paramètre de modèle. Vous n'avez pas besoin de modèles variadiques ici. Faites simplement ceci à la place :

template <
    template<class, std::size_t>  class T,
    class A, std::size_t N>
class C {

    T<A, N> storage;
};

int main(){
    C<std::array, int, 3> c; // works!
}

Si vous souhaitez utiliser des modèles variadiques, mettez-le également dans le paramètre du modèle :

template <
    template<typename...>  class T,
    typename... Types>
class C {

    T<Types...> storage;
};

Si vous souhaitez utiliser cette version mais que vous voulez toujours utiliser std::array vous pouvez créer un alias pour std::array qui a déjà une taille :

template<typename T>
using array3 = std::array<T, 3>;

C<array3, int> c;

Vous pouvez également créer une sorte d'alias de modèle qui vous permet de choisir la taille :

template<std::size_t n>
struct sized_array {
    template<typename T>
    using array = std::array<T, n>;
};

C<sized_array<5>::array, int>;

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X