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.

vectorde todos ellos. Ver aquíRespuestas:
Deberías usar en
std::size_tlugar 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
intastd::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]/4Para aclarar,
Asignifica el parámetro, de[temp.deduct.call]/1Como 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 unaAque sea idéntica aA. Comostd::arraytiene 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