web-dev-qa-db-fra.com

Avantages de l'auto dans les paramètres de modèle en C ++ 17

Quels sont les avantages de auto dans les paramètres de modèle qui seront (éventuellement) introduits avec C++ 17?

Est-ce simplement une extension naturelle de auto lorsque je souhaite instancier un code de modèle?

auto v1 = constant<5>;      // v1 == 5, decltype(v1) is int
auto v2 = constant<true>;   // v2 == true, decltype(v2) is bool
auto v3 = constant<'a'>;    // v3 == 'a', decltype(v3) is char

Que puis-je gagner de cette fonctionnalité de langue?

50
Damian

Le template <auto> _ feature ( P0127R1 ) a été acceptée en C++ lors de la réunion ISO C++ 2016 à Oulu, en Finlande.

Un mot clé auto dans un paramètre de modèle peut être utilisé pour indiquer un paramètre non typé dont le type est déduit au moment de l'instanciation. Cela aide de penser à cela comme un moyen plus pratique d'écrire:

template <typename Type, Type value>

Par exemple,

template <typename Type, Type value> constexpr Type constant = value;
constexpr auto const IntConstant42 = constant<int, 42>;

peut maintenant être écrit comme

template <auto value> constexpr auto constant = value;
constexpr auto const IntConstant42 = constant<42>;

où vous n'avez plus besoin de préciser explicitement le type. P0127R1 inclut également quelques exemples simples mais utiles dans lesquels utiliser template <auto> avec les paramètres de modèle variadic est très pratique, par exemple pour les implémentations de listes de compilation au moment de la compilation:

template <auto ... vs> struct HeterogenousValueList {};
using MyList1 = HeterogenousValueList<42, 'X', 13u>;

template <auto v0, decltype(v0) ... vs> struct HomogenousValueList {};
using MyList2 = HomogenousValueList<1, 2, 3>;

En pré-C++ 1z, alors que HomogenousValueList pourrait simplement être écrit sous la forme

template <typename T, T ... vs> struct Cxx14HomogenousValueList {};
using MyList3 = Cxx14HomogenousValueList<int, 1, 2, 3>;

écrire un équivalent de HeterogenousValueList ne serait pas possible sans inclure les valeurs dans d'autres modèles, par exemple:

template <typename ... ValueTypes> struct Cxx14HeterogenousValueList {};
using MyList4 = Cxx14HeterogenousValueList<constant<int, 42>,
                                           constant<char, 'X'> >;
57
mceo

En réalité, le cas des valeurs réelles dans la réponse de mceo (originale) n'est explicitement pas couvert en tant que paramètre de modèle non typé.

template <auto ... vs> struct HeterogenousValueList {};
using MyList1 = HeterogenousValueList<42, 'X', 1.3f>;

Voir l'exemple donné dans la proposition mentionnée: Modifier le paragraphe 14.3.2, paragraphe 2:

template<auto n> struct B { /* ... */ };
B<5> b1;   // OK: template parameter type is int
B<'a'> b2; // OK: template parameter type is char
B<2.5> b3; // error: template parameter type cannot be double

Je suis tombé sur la même idée fausse moi-même il y a quelques jours.

10
m-j-w

Voici un autre exemple ( présenté à l'origine par @ Rakete1111 comme réponse à paramètre de modèle de type inconn ):

Extraire la valeur de SIZE sans connaître son type:

template<std::size_t SIZE>
class Foo {};

template <template<auto> class T, auto K>
auto extractSize(const T<K>&) {
    return K;
}

int main() {
    Foo<6> f1;
    Foo<13> f2;
    std::cout << extractSize(f1) << std::endl;
    std::cout << extractSize(f2) << std::endl;
}
4
Amir Kirsh