Ventajas de auto en los parámetros de plantilla en C++17

Resuelto Damian asked hace 8 años • 4 respuestas

¿Cuáles son las ventajas de autolos parámetros de plantilla que (posiblemente) se introducirán con C++ 17?

¿Es solo una extensión natural autocuando quiero crear una instancia del código de plantilla?

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

¿Qué más gano con esta función de idioma?

Damian avatar Jun 25 '16 16:06 Damian
Aceptado

La template <auto>característica ( P0127R1 ) fue aceptada en C++ en la reunión ISO C++ 2016 en Oulu, Finlandia.

Se puede utilizar una autopalabra clave en un parámetro de plantilla para indicar un parámetro que no es de tipo cuyo tipo se deduce en el momento de la creación de instancias. Es útil pensar en esto como una forma más conveniente de escribir:

template <typename Type, Type value>

Por ejemplo,

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

ahora se puede escribir como

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

donde ya no es necesario explicar explícitamente el tipo. P0127R1 también incluye algunos ejemplos simples pero buenos donde el uso template <auto>con parámetros de plantilla variables es muy útil, por ejemplo, para implementaciones de listas de valores constantes en tiempo de compilación:

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 versiones anteriores a C++ 1z, aunque HomogenousValueListpodría escribirse simplemente como

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

escribir un equivalente de HeterogenousValueListno sería posible sin incluir los valores en otras plantillas, por ejemplo:

template <typename ... ValueTypes> struct Cxx14HeterogenousValueList {};
using MyList4 = Cxx14HeterogenousValueList<constant<int, 42>,
                                           constant<char, 'X'> >;
mceo avatar Jun 26 '2016 23:06 mceo

En realidad, el caso de valores reales en la respuesta (original) de mceo no se cubre explícitamente como parámetro de plantilla que no es de tipo.

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

Véase el ejemplo dado en la propuesta mencionada: Modificar §14.3.2 párrafo 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

Hace unos días me topé con el mismo concepto erróneo.

m-j-w avatar Jul 28 '2016 15:07 m-j-w

Aquí hay otro ejemplo ( presentado originalmente por @ Rakete1111 como respuesta para un parámetro de plantilla de tipo desconocido ):

Extrayendo el valor de TAMAÑO sin saber su 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;
}
Amir Kirsh avatar Feb 04 '2018 14:02 Amir Kirsh