generic - template class t c++ example
Deducción parcial de plantilla de clase C++ 17 (2)
De este excelente informe de viaje de Botond Ballo:
La característica propuesta originalmente incluía una disposición para la deducción parcial, en la que especifica explícitamente algunos de los argumentos de la plantilla y deja que se deduzca el resto, pero esto se detuvo por la preocupación de que puede ser muy confuso en algunos casos:
// Would have deduced tuple<int, string, float>, // but tuple<int> is a well-formed type in and of itself! tuple<int> t(42, "waldo", 2.0f);
Mi comprensión sobre la deducción de argumentos de plantilla para la propuesta de plantillas de clase fue homogeneizar el comportamiento de las funciones de plantilla y las clases de plantilla en contextos de deducción. Pero creo que he entendido mal algo.
Si tenemos este objeto de plantilla:
template <std::size_t S, typename T>
struct test
{
static constexpr auto size = S;
using type_t = T;
test(type_t (&input)[size]) : data(input) {}
type_t (&data)[size]{};
};
Tiendo a usar una función auxiliar como
azúcar sintáctica
para crear objetos de
test
:
template <std::size_t S, typename T>
test<S, T> helper(T (&input)[S]) { return input; }
Que se puede usar como se muestra a continuación:
int main()
{
int buffer[5];
auto a = helper<5, int>(buffer); // No deduction
auto b = helper<5>(buffer); // Type deduced
auto c = helper(buffer); // Type and size deduced
std::cout << a.size << b.size << c.size;
return 0;
}
El código anterior genera
555
como se esperaba.
He intentado lo mismo en Wandbox usando la nueva configuración del compilador
1
:
int main()
{
int buffer[5];
test<5, int> a(buffer); // No deduction: Ok.
test<5> b(buffer); // Type deduced: FAILS.
test c(buffer); // Type and size deduced: Ok.
std::cout << a.size << b.size << c.size;
return 0;
}
Parece que la deducción de argumentos de plantilla para plantillas de clase solo funciona deduciendo todos los parámetros, esperaba que ambos comportamientos (función auxiliar y plantilla de clase) fueran iguales, ¿entendí mal algo?
1 Los últimos compiladores disponibles en Wandbox son gcc HEAD 7.0.1 201701 y clang HEAD 5.0.0 (trunk) .
Parece que hay una contradicción aquí. Mirando P0091R3 , parece claro que se supone que se permiten parámetros de especificación parcial:
Proponemos permitir un nombre de plantilla que se refiera a una plantilla de clase como un especificador de tipo simple o con argumentos de plantilla explícitos parcialmente suministrados en dos contextos:
Pero la
redacción de los estándares reales
en la misma propuesta no proporciona una manera de manejar "argumentos de plantilla explícitos parcialmente suministrados".
template-name
como especificador de tipo simple no puede tener argumentos de plantilla.
Entonces, siguiendo la especificación en sí, el comportamiento del compilador parece ser correcto.