J'ai le code modèle suivant
#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);
}
qui produit
SPECIFIC (vector)
GENERIC
Je me demande pourquoi la version vecteur de vecteur est appelée avec le modèle spécifique, mais la version vecteur de tableau est appelée avec le générique?
vector
sur chacun d'eux. Voir iciRéponses:
Vous devez utiliser à la
std::size_t
place deint
. courir iciEdit: En fait, vos commentaires et mon intuition sur le code m'ont amené à creuser le sujet. À première vue, un développeur standard (comme moi) attendre compilateur pour convertir
int
àstd::size_t
(car ils sont à la fois type intégral et la conversion implicite est très trivial) et choisirvoid foo(std::vector<std::array<T1, SIZE>> bar)
comme meilleure spécialisation. Donc, en lisant la page de déduction des arguments du modèle, j'ai trouvé ceci:Comme toujours, bien sûr, vous devez lire plusieurs fois plus d'une fois pour comprendre ce que cela signifie :)
Un résultat intéressant en ressort donc.
Déjà notre spécialisation souhaitée n'est pas sélectionnée mais si le compilateur avait été forcé de sélectionner, ce serait une erreur.
exécuter du code
Une autre chose intéressante est:
Si l'argument de modèle non-type n'avait pas été déduit, il n'y aurait aucune restriction qui forcerait les types d'argument et de modèle à être identiques.
exécuter du code
la source
size_t
...Je pense que cela est simplement dû à une ligne de
[temp.deduct.call]/4
Pour clarifier,
A
signifie le paramètre, de[temp.deduct.call]/1
Comme cela a déjà été souligné, le fait de changer
template<typename T1, int SIZE>
pourtemplate<typename T1, size_t SIZE>
résoudre le problème que vous voyez. Comme indiqué dans[temp.deduct.call]/4
, le compilateur cherche à déduire unA
qui est identique àA
. Comme unstd::array
a des arguments de modèle<class T, size_t N>
(de[array.syn]
), son deuxième paramètre ne l'estsize_t
pasint
.Par conséquent, pour la déduction de modèle, votre fonction générique de
template<typename T1>
peut correspondre exactement au type deA
, où votre spécialistetemplate<typename T1, int SIZE>
n'est pas une correspondance exacte . Je crois que MSVC est incorrect dans sa déduction.la source