2016-06-11 14 views
5

Ich muss einen der feineren Punkte in Bezug auf emplace() und Freunde vermissen. Hier ist ein komplettes, minimales Beispiel, das das Problem mit g ++ 4.9.3 wiedergibt:g ++ 4.9.3 beschwert sich, dass friended ctor mit .emplace_back() privat ist, mag aber .push_back()

class Foo 
{ 
public: 
    class Bar 
    { 
    private: 
    friend class Foo; 
     Bar(Foo &foo) : foo(foo) {} 
     Foo &foo; 
    }; 

    Bar &getBar() 
    { 
     //bars.push_back(*this);  // works fine 
     bars.emplace_back(*this);  // Foo::Bar::Bar(Foo&) is private 
     return bars.back(); 
    } 
private: 
    std::vector<Bar> bars; 
}; 
+3

Ich rollte Ihre Bearbeitung zurück. Bitte ändere deine Fragen nicht, nachdem du Antworten erhalten hast. Wenn Sie eine neue Frage haben, geben Sie eine neue Frage ein. – Barry

Antwort

10

In emplace_back, der Behälter ist derjenige, der Bar konstruiert. Aber dieser Konstruktor ist privat und der Container ist kein Freund, also scheitert es.

Aber push_back(*this) entspricht push_back(Bar(*this)). Das heißt, es ist die Foo, die die Konstruktion macht und es ist ein Freund.

+0

Beeindruckend. Irgendwelche Gedanken, wie man den Container zum Freund macht? – Steger

+0

@Steger können Sie nicht garantieren, dass es funktionieren würde, da es eine nicht spezifizierte Basisklasse sein könnte, die die Konstruktion ausführt. – Barry

2
bars.emplace_back(*this); 

verzögert den Aufruf an den Konstruktor Bar(Foo&) zu std::vector::emplace_back(). Diese Funktion verfügt nicht über die Zugriffsberechtigung zum Aufrufen von Bar(Foo&).

Auf der anderen Seite,

bars.push_back(*this); 

ruft den Konstruktor Bar(Foo&) vor dem Aufruf von std::vector::push_back(). Das ist kein Problem, da Foo ein friend von Bar ist.