2011-01-16 19 views
3

den folgenden Code vor:Umgebung Zugriffsbezeichner mit C++ 0x decltype

class A 
{ 
private: 
    class B {}; 
public: 
    B f(); 
}; 

A a; 

A::B g() 
{ 
    return a.f(); 
} 

Der Compiler dies ablehnt - g kann ein :: B nicht zurück, weil A :: B privat ist.

Aber ich nehme jetzt decltype verwenden den Rückgabewert von g zu spezifizieren:

class A 
{ 
private: 
    class B {}; 
public: 
    B f(); 
}; 

A a; 

decltype(a.f()) g() 
{ 
    return a.f(); 
} 

Urplötzlich es fein kompiliert (mit g ++> = 4.4).

Also habe ich declltype verwendet, um einen Access Specifier zu umgehen, wie ich es in C++ 98 nicht geschafft hätte.

Ist das beabsichtigt? Ist das eine gute Praxis?

+1

bezogen: [delegiert in private Teile] (http://stackoverflow.com/questions/2952216/) – fredoverflow

Antwort

5

Zugriff gilt nur für Namen (und als Sonderfall für Konstruktoren/Destruktoren). Es gilt nicht für Entitäten selbst. Die Spezifikation weiter ausarbeitet

[Anmerkung: weil Zugriffskontrolle auf Namen gilt, wenn Zugriffssteuerung auf einen typedef Namen angelegt wird, nur die Zugänglichkeit des typedef Namen selbst betrachtet wird. Die Erreichbarkeit der Entität, auf die sich typedef bezieht, wird nicht berücksichtigt. Zum Beispiel

class A { 
    class B { }; 
public: 
    typedef B BB; 
}; 

void f() { 
    A::BB x; // OK, typedef name A::BB is public 
    A::B y; // access error, A::B is private 
} 

- Endnote]

Was haben Sie hier disovered ist nicht verwunderlich. Sie können den Typ A::B sogar in C++ 03 erhalten, wenn Sie die Adresse f mit &A::f annehmen und an eine Funktionsvorlage übergeben, die den Rückgabetyp ableitet.