Vantagens dos parâmetros do modelo automático em C++17

Quais são as vantagens de auto nos parâmetros do modelo que serão (possivelmente) introduzidos com o C++17?

é apenas uma extensão natural de auto Quando eu quero instanciar o código modelo?

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 mais ganho com este recurso de linguagem?

Author: Damian, 2016-06-25

4 answers

A funcionalidade template <auto> (P0127R1) foi aceite em C++ na reunião ISO C++ 2016 em Oulu, Finlândia.

Uma palavra-chave auto num parâmetro de modelo pode ser usada para indicar um parâmetro não-Tipo cujo tipo é deduzido no ponto de instanciação. Ajuda pensar nisto como uma forma mais conveniente de escrever:

template <typename Type, Type value>

Por exemplo,

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

Agora pode ser escrito como

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

Onde você não precisa de soletrar explicitamente o tipo qualquer mais. P0127R1 também inclui alguns exemplos simples, mas bons, onde a utilização de template <auto> com parâmetros de modelo variádicos é muito útil, por exemplo para implementações de listas de tempo de compilação valores constantes:

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

Em pre-C++1z, enquanto HomogenousValueList pode ser simplesmente escrito como

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

Escrever um equivalente de HeterogenousValueList não seria possível sem envolver os valores em alguns outros modelos, por exemplo:

template <typename ... ValueTypes> struct Cxx14HeterogenousValueList {};
using MyList4 = Cxx14HeterogenousValueList<constant<int, 42>,
                                           constant<char, 'X'> >;
 73
Author: mceo, 2017-01-11 22:09:09

Na verdade, o caso dos valores reais na resposta do mceo (original) não é explicitamente abrangido como parâmetro do modelo não-Tipo.

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

Ver o exemplo apresentado na proposta mencionada.: Modificar o ponto 14.3.2, n. o 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
Tropecei no mesmo erro que eu há alguns dias.
 13
Author: m-j-w, 2017-03-16 22:33:18

Aqui está outro exemplo (originalmente apresentado por @Rakete1111 como resposta para o parâmetro do modelo do tipo desconhecido):

Extrair o valor do tamanho sem saber o seu tipo:

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;
}
 6
Author: Amir Kirsh, 2018-02-04 14:24:48

O C++20 parecia adicionar outra utilização

... mas não ...

As concepts technical specification allowed a function parameter with auto template argument placeholder, e.g.:

void printPair(const std::pair<auto, auto>& p) {
    std::cout << p.first << ", " << p.second << std::endl;
}

Mas foi removido mais tarde na especificação C++20.

Este é um uso limpo... Espero que volte a entrar em C++23!

Ver: 'auto' como substituição de argumentos do modelo para um parâmetro de função

 1
Author: Amir Kirsh, 2020-04-02 01:15:25