Zeigerabfall und Funktionsüberladungsauflösung
In C zielt die Überladungsauflösung darauf ab, die am besten passende Funktion für einen bestimmten Satz von Argumenten auszuwählen. Wenn mehrere Funktionen in Frage kommen, wird diejenige mit den minimalen Konvertierungskosten bevorzugt.
Betrachten Sie die folgende Funktionsvorlage, die die Länge eines Zeichenarrays ausgibt:
template <size_t N> void foo(const char (&s)[N]) { std::cout << "array, size=" << N - 1 << std::endl; }
Beim Aufruf von foo( „hello“) identifiziert es erfolgreich die Template-Spezialisierung und gibt „array, size=5“ aus. Die Erweiterung von foo zur Unterstützung von Nicht-Array-Szenarien führt jedoch zu Mehrdeutigkeiten.
void foo(const char* s) { std::cout << "raw, size=" << strlen(s) << std::endl; }
Der Aufruf von foo("hello") gibt nun überraschenderweise "raw, size=5" aus, obwohl die Template-Spezialisierung wie eine aussieht genauere Übereinstimmung.
Der Grund für die Mehrdeutigkeit
Die Mehrdeutigkeit entsteht, weil ein Array im Wesentlichen ein Zeiger auf sein erstes Element ist, was eine Array-zu-Zeiger-Konvertierung kostengünstig macht. Gemäß den C-Überladungsauflösungsregeln wird eine Überladung bevorzugt, die weniger Konvertierungsvorgänge erfordert. In diesem Fall handelt es sich bei der Array-zu-Zeiger-Konvertierung um eine kostengünstige L-Wert-Transformation, die einen höheren Rang einnimmt als der erforderliche Vorlagenargumentabzug.
Umgehung der Mehrdeutigkeit
Um sicherzustellen, dass die Array-Funktionsüberladung aufgerufen wird, besteht eine Problemumgehung darin, die Nicht-Array-Überladung als Funktionsvorlage zu definieren Nun ja:
template <typename T> auto foo(T s) -> std::enable_if_t<std::is_convertible<T, char const*>{}> { std::cout << "raw, size=" << std::strlen(s) << std::endl; }
Dadurch wird sichergestellt, dass die Vorlagenspezialisierung priorisiert wird, da die teilweise Reihenfolge einsetzt.
Das obige ist der detaillierte Inhalt vonWarum wirkt sich der Zeigerabfall auf die Überladungsauflösung in C-Funktionsvorlagen aus?. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!