Heim  >  Artikel  >  Backend-Entwicklung  >  Warum überschreibt der Zeigerabfall den Vorlagenabzug beim Überladen von C-Funktionen?

Warum überschreibt der Zeigerabfall den Vorlagenabzug beim Überladen von C-Funktionen?

Mary-Kate Olsen
Mary-Kate OlsenOriginal
2024-11-21 16:11:14562Durchsuche

Why Does Pointer Decay Override Template Deduction in C   Function Overloading?

Zeigerzerfall hat Vorrang vor Vorlagenableitung

Beim Schreiben von Code, der mit Zeichenfolgen arbeitet, stößt man häufig auf ein Dilemma, bei dem versucht wird, zu überladen Eine Funktion, die sowohl Array-basierte als auch Nicht-Array-basierte Zeichenfolgendarstellungen berücksichtigt, kann zu unerwartetem Verhalten führen.

In diesem Fall Szenario wird eine anfängliche Funktion foo definiert, um die Länge eines Arrays von Zeichen auszugeben:

template <size_t N>
void foo(const char (&s)[N]) {
    std::cout << "array, size=" << N-1 << std::endl;
}

Diese Funktion akzeptiert Arrays von Zeichen und gibt die Array-Länge aus. Wenn jedoch foo erweitert wird, um auch Nicht-Array-Zeichenfolgen zu verarbeiten, entsteht Mehrdeutigkeit:

void foo(const char* s) {
    std::cout << "raw, size=" << strlen(s) << std::endl;
}

Die Absicht besteht darin, dass die zweite foo-Überladung Nicht-Array-Zeichenfolgen verarbeiten soll Zeichenfolgen, aber überraschenderweise führt diese Erweiterung dazu, dass die ursprüngliche Überladung sowohl für Arrays als auch für Nicht-Arrays umgangen wird Zeichenfolgen:

foo("hello") // prints raw, size=5

Dieses unerwartete Verhalten ist auf das Konzept des Zeigerzerfalls zurückzuführen. Arrays sind im Wesentlichen Zeiger auf ihr erstes Element, und die Konvertierung eines Arrays in einen Zeiger ist eine sehr kostengünstige Operation. Infolgedessen priorisiert der Compiler die Überladung, die einen Zeigerparameter akzeptiert, auch wenn dafür eine implizite Konvertierung vom Array-Argument erforderlich ist.

Um das gewünschte Verhalten sicherzustellen, wenn die Array-basierte Überladung für Arrays verwendet wird, Es ist notwendig, eine zusätzliche Überladung einzuführen:

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;
}

Diese Überladung nutzt die Vorlagenableitung und beschränkt ihre Anwendbarkeit auf Typen, die in Zeichenzeiger konvertiert werden können. Durch die teilweise Sortierung wählt der Compiler nun korrekt die entsprechende foo-Funktion basierend auf dem Argumenttyp aus.

Das obige ist der detaillierte Inhalt vonWarum überschreibt der Zeigerabfall den Vorlagenabzug beim Überladen von C-Funktionen?. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Stellungnahme:
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn