2013-11-06 2 views
5
#include <iostream> 
#include <vector> 
#include <memory> 
using namespace std; 

struct BinaryTree 
{ 
    int element;  
    shared_ptr<BinaryTree> left; 
    shared_ptr<BinaryTree> right; 
}; 

int main() 
{ 
    vector<shared_ptr<BinaryTree>> vecBT; 

    // case I 
    vecBT.emplace_back(new BinaryTree{10, nullptr, nullptr}); 

    // case II 
    vecBT.emplace_back(shared_ptr<BinaryTree>(new BinaryTree{20, nullptr, nullptr})); 

    return 0; 
} 

http://en.cppreference.com/w/cpp/container/vector/emplace_back 
template< class... Args > 
void emplace_back(Args&&... args); 

http://en.cppreference.com/w/cpp/memory/shared_ptr/shared_ptr 
template< class Y > 
explicit shared_ptr(Y* ptr); 

Вопрос> Я составил приведенный выше код через http://www.compileonline.com/compile_cpp11_online.php без ошибок.Использование вектора :: emplace_back с shared_ptr

Мой вопрос в том, как case I может передать компилятор без возникновения ошибок. Поскольку конструктор shared_ptr требует явной конструкции. Поэтому я ожидаю, что только case II верен.

+0

Вы ответили сами. Вы также можете использовать 'push_back'. – user1095108

+0

Дело, в котором я работаю, но я не знаю почему. – q0987

+1

@ q0987 аргумент emplace_back не является shared_ptr, поэтому там нет неявной конструкции. Скорее это переменное количество аргументов, которые должны быть переданы в contructor shared_ptr, который затем может быть вызван явно. – KillianDS

ответ

5

Оба случая верны, конструктор std::shared_ptr является явным, но это именно то, что вызывается из emplace_back, которое просто перенаправляет свои аргументы в явный вызов конструктора. Это отличается от принятия std::shared_ptr в качестве аргумента и запроса неявного преобразования.

+0

Да, как бы «вектор» конструировал что-либо в противном случае? – user1095108

+0

Я не уверен в эффективности 'std :: make_shared', но это определенно лучше, чем голый' новый', так как вы не будете течь, если конструктор выбрасывает. EDIT: Вы удалили это из своего сообщения, но я думаю, что это все еще актуально. –

+1

@SamCristall Пришлось удалить его, как в этом конкретном случае, он не может использоваться, поскольку OP хочет инициализировать агрегат. –

Смежные вопросы