2016-06-11 2 views
5

Je dois manquer l'un des points les plus fins concernant emplace() et les amis. Voici un exemple complet, un minimum qui reproduit le problème avec g ++ 4.9.3:g ++ 4.9.3 se plaint que ctor ami est privé avec .emplace_back(), mais aime .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

J'ai annulé votre modification. S'il vous plaît ne pas changer vos questions après avoir reçu des réponses. Si vous avez une nouvelle question, postez une nouvelle question. – Barry

Répondre

10

En emplace_back, le conteneur est celui qui construit le Bar. Mais ce constructeur est privé et le conteneur n'est pas un ami, donc il échoue. Mais push_back(*this) est équivalent à push_back(Bar(*this)). C'est, c'est le Foo qui fait la construction et c'est un ami.

+0

Impressionnant. Des idées sur la façon de faire du conteneur un ami? – Steger

+0

@Steger vous ne pouvez pas garantir que cela fonctionnerait, car il pourrait s'agir d'une classe de base non spécifiée qui fait la construction. – Barry

2
bars.emplace_back(*this); 

retarde l'appel au constructeur Bar(Foo&) à std::vector::emplace_back(). Cette fonction n'a pas le privilège d'accès pour appeler Bar(Foo&).

D'autre part,

bars.push_back(*this); 

appelle le constructeur Bar(Foo&) avant l'appel à std::vector::push_back(). Ce n'est pas un problème puisque Foo est un friend de Bar.