2016-06-11 26 views
5

Muszę brakować jednego z lepszych punktów dotyczących emplace() i przyjaciół. Oto kompletna, minimalny przykład, który reprodukuje problem z g ++ 4.9.3:g ++ 4.9.3 narzeka, że ​​znajomy ctor jest prywatny z .emplace_back(), ale lubi .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

Wycofałem Twoją zmianę. Nie zmieniaj pytań po otrzymaniu odpowiedzi. Jeśli masz nowe pytanie, opublikuj nowe pytanie. – Barry

Odpowiedz

10

W emplace_back, pojemnik jest tym, który konstruuje Bar. Ale ten konstruktor jest prywatny i kontener nie jest przyjacielem, więc nie działa.

Ale push_back(*this) jest odpowiednikiem push_back(Bar(*this)). Oznacza to, że jest to Foo, który wykonuje konstrukcję i jest przyjacielem.

+0

Imponujące. Jakieś przemyślenia na temat tego, jak uczynić kontener przyjacielem? – Steger

+0

@Steger nie można zagwarantować, że będzie działać, ponieważ może to być nieokreślona klasa bazowa, która wykonuje konstrukcję. – Barry

2
bars.emplace_back(*this); 

opóźnia wywołanie konstruktora Bar(Foo&) do std::vector::emplace_back(). Ta funkcja nie ma uprawnień dostępu do wywoływania Bar(Foo&).

Z drugiej strony,

bars.push_back(*this); 

wywołuje konstruktor Bar(Foo&) przed wywołaniem std::vector::push_back(). Nie stanowi to problemu, ponieważ Foo jest friend z friend z friend z.