2016-06-11 9 views
5

Мне не хватает одного из самых тонких вопросов относительно emplace() и друзей. Вот полный, минимальный пример, который воспроизводит проблему с г ++ 4.9.3:g ++ 4.9.3 жалуется, что дружественный ctor является приватным с .emplace_back(), но любит .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

Я откатил ваше редактирование. Пожалуйста, не меняйте свои вопросы после получения ответов. Если у вас есть новый вопрос, задайте новый вопрос. – Barry

ответ

10

В emplace_back, контейнер является тот, который строит Bar. Но этот конструктор является закрытым, и контейнер не является другом, поэтому он терпит неудачу.

Но push_back(*this) равнозначно push_back(Bar(*this)). То есть, это Foo, который делает конструкцию, и это друг.

+0

Впечатляет. Любые мысли о том, как сделать контейнер другом? – Steger

+0

@Steger вы не можете гарантировать, что это сработает, поскольку это может быть неуказанный базовый класс, который выполняет конструкцию. – Barry

2
bars.emplace_back(*this); 

задерживает вызов конструктора Bar(Foo&) к std::vector::emplace_back(). Эта функция не имеет права доступа для вызова Bar(Foo&).

С другой стороны,

bars.push_back(*this); 

вызывает конструктор Bar(Foo&) перед вызовом std::vector::push_back(). Это не проблема, поскольку Foo является friend от Bar.