2010-12-09 17 views
4

Was bedeutet folgendes (besonders der hervorgehobene Teil)? Warum wird der Ausdruck "f (a)" als "Besetzung" behandelt? ..Freund Funktion

C++ 03 $ 3.4/3- „Die Suche für einen nicht qualifizierten Namen als Postfix-Ausdruck eines Anrufs Funktion in 3.4.2 beschrieben [Hinweis: für die Zwecke der Bestimmung (während der Syntaxanalyse), ob ein Ausdruck ist ein postfix-Ausdruck für eine Funktion Aufruf, die übliche Namenssuche Regeln gelten . die Regeln in 3.4.2 haben keine Wirkung auf die syntaktische Interpretation eines Ausdrucks. zum Beispiel

typedef int f; 
struct A { 
friend void f(A &); 
operator int(); 
void g(A a) { 
f(a); 
} 
}; 

Der Ausdruck f (a) ist ein Cast-Ausdruck, der äquivalent zu int (a) ist. Da der Ausdruck kein Funktionsaufruf ist, gilt die Argument-abhängige Namenssuche (3.4.2) nicht und die Friend-Funktion f wird nicht gefunden. „]

Irgendwelche Gedanken?

Antwort

1

Es bedeutet, dass der Parser bestimmt zuerst, ob der Ausdruck vor den Klammern ist ein id oder ein Postfix-Ausdruck. In diesem Fall ist es sieht f und die nächste f definiert ist typedef int f - deshalb schließt es der Ausdruck als int(a) und kein Koenig-Lookup interpretiert wird, durchgeführt

der diesen Code Lassen Sie haben (ein, Sie versuchen es online: http://ideone.com/clone/eRKvP)

.
typedef int f; 
namespace x { 
    struct A { 
    friend void f(A &); 
    //friend void f(); // # 1 
    operator int(); 
    void g(A a) { 
     //void f(); // # 2 
     (void)f(a); // # 3 
    } 
    }; 
} 

Haben Sie eine (nicht verwandte) erklärten Funktion f sichtbar von g, würde es als Funktionsaufruf und Koenig-Lookup die richtige Überlastung finden würde interpretiert werden (siehe Linie #2).

Der Freund Erklärung f sollte hier nicht gelten, weil

11,4/1 ... Der Name eines Freundes nicht in den Geltungsbereich der Klasse ist,

jedoch Was stört mich, ist, dass das Auskommentieren #1 macht den Compiler (gcc in diesem Fall) x::f(A&) aufrufen. Nicht sicher, warum ist das so? [Im Comeau Online Compiler funktioniert es wie erwartet (zB #1 beeinflusst nicht die Zeile #3). Die neueste Beta-Version hat Probleme diesen Code kompilieren, obwohl]

. PS: Wie litb erwähnt, sind die Regeln in C++ 0x ein wenig anders:

3.4.2/3:

Sei X die Lookup-Set von unquali fi zierten Lookup (3.4.1) und lassen Y die Lookup-Set durch das Argument abhängige Lookup (definiert wie folgt) hergestellt werden hergestellt werden. Wenn X enthält

  • eine Erklärung eines Klassenmitglied oder
  • eine Block-scope Funktionsdeklaration, die keine Verwendung von-Deklaration ist, oder
  • eine Erklärung, dass weder eine Funktion ist, oder einer Funktionsvorlage

dann ist Y leer. Ansonsten ist Y die Menge von Deklarationen in den mit den

Der fett gedruckten Artikeln

zugeordnet Namespace gefunden wird, die Compiler machen nur void f() betrachten und zu viele Argumente versagen.

Es scheint durch die Auflösung issue 218 eingeführt worden zu sein.

+1

Auskommentierung # 2 deaktivieren koenig Suche nach C++ 0x Regeln, obwohl einige Compiler diese Regeln auch im C++ 03-Modus verwenden. Es würde also als Funktionsaufruf kompiliert werden, aber als Aufruf der lokal deklarierten Funktion und würde einen Fehler verursachen. –

+0

@Johannes Schaub - litb: Neugierig zu wissen, warum die friend-Funktion nicht während der Namenssuche gefunden wird, obwohl sie im lexikalischen Bereich der Klasse liegt. – Chubsdad

+0

@Chubsdad: Das liegt daran, dass es nicht im Rahmen der Klasse ist. – jpalecek