Ich habe den folgenden Vorlagencode
#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);
}
was produziert
SPECIFIC (vector)
GENERIC
Ich frage mich, warum die Vektor-von-Vektor-Version mit der spezifischen Vorlage aufgerufen wird, aber die Vektor-von-Array-Version mit der generischen?
vector
bei allen das Äußere entfernen . Siehe hierAntworten:
Sie sollten
std::size_t
anstelle von verwendenint
. lauf hierBearbeiten: Eigentlich haben mich Ihre Kommentare und meine Intuition bezüglich des Codes dazu gebracht, mich mit dem Thema zu befassen. Auf den ersten Blick ein Standard - Entwickler (wie ich) erwarten Compiler zu konvertieren
int
zustd::size_t
(weil sie beide integralen Typ sind und implizit Umwandlung ist sehr trivial) und wählen Sievoid foo(std::vector<std::array<T1, SIZE>> bar)
als beste Spezialisierung. Beim Lesen der Seite zum Abzug von Vorlagenargumenten habe ich Folgendes gefunden:Wie immer müssen Sie natürlich mehrmals lesen, um zu verstehen, was es bedeutet :)
Es ergibt sich also ein interessantes Ergebnis.
Unsere gewünschte Spezialisierung ist bereits nicht ausgewählt, aber wenn der Compiler zur Auswahl gezwungen worden wäre, wäre dies ein Fehler.
Code ausführen
Eine andere interessante Sache ist:
Wenn das Nicht-Typ-Vorlagenargument nicht abgeleitet worden wäre, gäbe es keine Einschränkung, die die Gleichheit von Argument und Vorlagentyp erzwingt.
Code ausführen
quelle
size_t
...Ich denke das liegt einfach an einer Zeile von
[temp.deduct.call]/4
Zur Verdeutlichung
A
bedeutet der Parameter von[temp.deduct.call]/1
Wie bereits erwähnt, wird
template<typename T1, int SIZE>
dastemplate<typename T1, size_t SIZE>
angezeigte Problem durch Ändern auf behoben. Wie in angegeben,[temp.deduct.call]/4
versucht der Compiler, eine zu schließenA
, die mit identisch istA
. Da einstd::array
Template-Argument<class T, size_t N>
(von[array.syn]
) hat, ist sein zweiter Parameter tatsächlichsize_t
nichtint
.Daher wird für die Vorlage Abzug, Ihre generische Funktion
template<typename T1>
ist in der Lage zu passen genau die Art vonA
, wo-wie Ihre spezialisierttemplate<typename T1, int SIZE>
ist keine genaue Übereinstimmung. Ich glaube, MSVC ist in seinem Abzug falsch.quelle