2016-10-24 4 views
3
zu funktionieren

Ich war auf der Suche über den folgenden Code:Überladene Zeiger

string toUpper(string s) { 
    string result; 
    int (*toupperp)(int) = &toupper; // toupper is overloaded 
    transform(begin(s), end(s), back_inserter(result), toupperp); 
    return result; 
} 

ich von dieser Linie bin verwirrt:

int (*toupperp)(int) = &toupper; // toupper is overloaded 

1.Why ist diese Linie notwendig?

2.Ich glaube, dass & einen Zeiger auf etwas aus dem Speicher abruft. Aber toupper, der Name der Funktion ist schon ein Zeiger, nein? Warum können wir das nicht tun:

int (*toupperp)(int) = toupper; 

3.Warum die Funktion int überlastet ist, wenn es auf einem string verwendet wird?

+0

3. Es wird nicht auf 'string', sondern auf jedem' char' der 'string' verwendet. – Jarod42

Antwort

5

1) Es ist nicht notwendig, wirklich. Wenn Sie die Anweisung using namespace std verwendet haben, müssen Sie den gewünschten Typ in let the compiler know which overload you want eingeben. So könnte man auch sagen,

transform(begin(s), end(s), back_inserter(result), static_cast<int(*)(int)>(&toupper)); 

Ansonsten folgend genug sein soll:

transform(begin(s), end(s), back_inserter(result), ::toupper); 

2) Bezeichner, die Funktionsnamen Zerfall in Zeiger sind, ja, aber sie sind nicht genau das gleiche. Davon abgesehen, in diesem Fall sollte es in Ordnung sein

int (*toupperp)(int) = toupper; 

zu sagen, oder sogar (wenn Sie nicht using namespace std Richtlinie verwendet haben):

auto toupperp = toupper; 

3) es ist für die Kompatibilität mit C-Standardbibliothek. Es wird für jedes Element von s verwendet, das für string ein char ist.

+0

Ich denke ['toupper'] (http://www.cplusplus.com/reference/cctype/toupper/) hat keine Überladung, oder? – Antonio

+0

@ Antonio guten Punkt zur Klarstellung.':: toupper' ist nicht überladen, aber' std :: toupper' ist - sehen Sie in [''] (http://en.cppreference.com/w/cpp/locale/toupper) – krzaq

+0

Es gibt auch eine [ sehr interessanter Kommentar] (http://stackoverflow.com/questions/2942426/how-do-i-specify-a-pointer-to-a-overloaded-function/2942442#comment7190884_2942442) auf warum die Verwendung der Zwischenvariable vorzuziehen ist, Ich habe heute etwas gelernt – Antonio

4

Was Sie an transform übergeben, ist ein Zeiger auf die Funktion toupper (siehe function pointers). Sie speichern diesen Zeiger in der lokalen Variablen toupperp. Der Typ von toupperp ist ein Zeiger auf eine Funktion, die ein int als Argument nimmt und einen int zurückgibt.

Wenn toupper auf seltsame Weise definiert ist, wird die Funktion scheinbar von transform verwendet, um jedes Eingabezeichen in Großbuchstaben zu ändern. Jedes einzelne Zeichen wird als Ganzzahl verarbeitet (bei Bedarf mit einer impliziten Umwandlung).

In Bezug auf Ihre Frage 2, mit dem Operator & machen Sie expliziter nehmen Sie die Adresse der Funktion, aber in der Tat könnten Sie es weglassen. Siehe here (ich habe heute etwas gelernt).

Wenn toupper überlastet wurde, ist die Verwendung der Zwischenvariablen ein sicherer Weg, um genau die gewünschte Überlast zu erhalten. Wenn die gewünschte Überladung verschwindet, fängt diese Methode das Problem zur Kompilierungszeit auf. Siehe here. (Und das ist etwas, was ich heute gelernt habe).