Tengo el siguiente código con plantilla
#include <vector>
#include <array>
#include <iostream>
template<typename T1>
void foo(std::vector<T1> bar) {
std::cout << "GENERIC" << std::endl;
}
template<typename T1>
void foo(std::vector<std::vector<T1>> bar) {
std::cout << "SPECIFIC (vector)" << std::endl;
}
template<typename T1, int SIZE>
void foo(std::vector<std::array<T1, SIZE>> bar) {
std::cout << "SPECIFIC (array)" << std::endl;
}
int main() {
std::vector<std::vector<int>> a(2, std::vector<int> { 1, 2, 3});
std::vector<std::array<int, 3>> b(2, std::array<int, 3> {4, 5, 6});
foo(a);
foo(b);
}
que produce
SPECIFIC (vector)
GENERIC
Me pregunto por qué la versión de vector de vector se llama con la plantilla específica, pero la versión de vector de matriz se llama con el genérico.
vector
de todos ellos. Ver aquíRespuestas:
Deberías usar en
std::size_t
lugar deint
. corre aquiEditar: En realidad, sus comentarios y mi intuición sobre el código me llevaron a profundizar en el tema. A primera vista, un desarrollador estándar (como yo) esperan compilador para convertir
int
astd::size_t
(porque ambos son de tipo integral e implícitamente la conversión es muy trivial) y seleccionarvoid foo(std::vector<std::array<T1, SIZE>> bar)
la mejor especialización. Entonces, mientras lee la deducción de argumento de plantilla página de encontré esto:Como siempre, por supuesto, debes leer algunas veces más de una vez para entender lo que significa :)
Entonces sale un resultado interesante.
Nuestra especialización deseada ya no está seleccionada, pero si el compilador se hubiera visto obligado a seleccionar, sería un error.
Ejecutar código
Otra cosa interesante es:
Si no se hubiera deducido el argumento de plantilla sin tipo, no habría restricción que obligue a que los tipos de argumento y plantilla sean iguales.
Ejecutar código
fuente
size_t
...Creo que esto se debe simplemente a una línea de
[temp.deduct.call]/4
Para aclarar,
A
significa el parámetro, de[temp.deduct.call]/1
Como ya se ha señalado, cambiar
template<typename T1, int SIZE>
paratemplate<typename T1, size_t SIZE>
solucionar el problema que está viendo. Como se indica en[temp.deduct.call]/4
, el compilador está buscando deducir unaA
que sea idéntica aA
. Comostd::array
tiene argumentos de plantilla<class T, size_t N>
(desde[array.syn]
), su segundo parámetro es, de hechosize_t
, noint
.Por lo tanto, para la deducción de plantilla, su función genérica de
template<typename T1>
puede coincidir exactamente con el tipo deA
, donde, como su especialistatemplate<typename T1, int SIZE>
no es una coincidencia exacta . Creo que MSVC es incorrecto en su deducción.fuente