Attempting to create a vector of shared_ptr to int.
Where am I going wrong? Thanks. Keith :^)
#include <iostream>
#include <vector>
#include <memory>
int main() {
    std::vector<std::shared_ptr<int> > w;
    std::vector<std::shared_ptr<int> >::iterator it_w;
    w.push_back(new int(7));
    std::cout << std::endl;
}
Compiler result:
pickledegg> g++ -std=c++11 -o shared_ptr shared_ptr.cpp
shared_ptr.cpp:29:4: error: no matching member function for call to 'push_back'
        w.push_back(new int(7));
        ~~^~~~~~~~~
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../include/c++/v1/vector:697:36: note: 
      candidate function not viable: no known conversion from 'int *' to 'const value_type' (aka
      'const std::__1::shared_ptr<int>') for 1st argument
    _LIBCPP_INLINE_VISIBILITY void push_back(const_reference __x);
                                   ^
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../include/c++/v1/vector:699:36: note: 
      candidate function not viable: no known conversion from 'int *' to 'value_type' (aka
      'std::__1::shared_ptr<int>') for 1st argument
    _LIBCPP_INLINE_VISIBILITY void push_back(value_type&& __x);
                                   ^
1 error generated.
                The std::shared_ptr<T> constructor that accepts raw pointers is marked explicit. source. You will not be able to call push_back with a raw pointer, as it's not implicitly convertible to std::shared_ptr<int> which is what push_back takes as an argument. The solution is to either use emplace_back instead of push_back or to use std::make_shared<int>.
emplace_back matches the parameters given to one of T's constructors.
w.emplace_back(new int(7));
std::make_shared<int> returns an object of type std::shared_ptr<int>, avoiding this problem.
w.push_back(std::make_shared<int>(7));
You may combine these solutions.
#include <iostream>
#include <vector>
#include <memory>
int main(int argc, char** argv) {
    std::vector<std::shared_ptr<int> > w;
    std::vector<std::shared_ptr<int> >::iterator it_w;
    w.emplace_back(std::make_shared<int>(7));
    std::cout << std::endl;
}
Edit: As an additional note, always prefer std::make_shared<T>(...) over std::shared_ptr<T>(new T(...)). It is designed to avoid very subtle potential memory leaks. It also elegantly avoids the situation where you have new without delete which may bother some people.
Edit 2: Additionally, std::make_shared<T>(...) has a performance  advantage where it avoids an additional allocation in `std::shared_ptr(new T(...))' see this answer.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With