12

So I am working on a transformation from an OO-language with garbage collection capabilities to C++. To start out I want to wrap all objects in shared pointers to solve the memory de-allocation issue. Right now I am trying to wrap a vector in a shared pointer and initializing the vector directly. See the issue below. Why is it not working and, if possible, how do I make it work?

vector<int> vec({ 6, 4, 9 }); // Working

shared_ptr<vector<int>> vec = make_shared<vector<int>>({ 6, 4, 9 }); // Not working

Sorry for not including the error, the error I am getting is marked at (make_shared) and printed as:

no instance of function template "std::make_shared" matches the argument list
argument types are: ({...})

Thanks for any answers!

Flipbed
  • 719
  • 9
  • 18
  • "Not working" eh? Huh, how about that. – John Zwinck Mar 05 '15 at 12:07
  • Sorry about that, I have added the error now. – Flipbed Mar 05 '15 at 12:14
  • The first, working, version is "better". `vector` already functions as a smart pointer around its contained data buffer. No need to wrap it up again, especially as you don't seem to actually be sharing it with anyone. You are just making the code slower, not more correct. – BoBTFish Mar 05 '15 at 12:21

4 Answers4

13

Brace initializer list cannnot be used in most type deduction contexts.

If you explicitly specify the type it works:

std::shared_ptr<std::vector<int>> vec = std::make_shared<std::vector<int>>(std::vector<int>{ 6, 4, 9 });
Drax
  • 12,682
  • 7
  • 45
  • 85
3
auto vec = make_shared<vector<int>>(std::initializer_list<int>{ 6, 4, 9 });
nh_
  • 2,211
  • 14
  • 24
0

Initializer lists don't play well with make_shared. For more detail, see here: std::make_shared with std::initializer_list

But probably the real solution is to not hold your vector in a smart pointer at all--not everything deserves a smart pointer anyway. But if you want to stick with it, this should work:

shared_ptr<vector<int>> vec(new vector<int>({ 6, 4, 9 }));
Community
  • 1
  • 1
John Zwinck
  • 239,568
  • 38
  • 324
  • 436
  • I was hoping to use the make_shared function since I have read that creating shared pointers that way increases performance significantly and the code is supposed to be run on embedded systems which means that I have to focus a lot on performance. – Flipbed Mar 05 '15 at 12:13
  • 1
    If it is to be run on embedded system, why have a shared_ptr? it provides a bit of an overhead. – Hayden Mar 05 '15 at 12:14
  • Hayden, I am aware of that, but as of now I need some way to handle the memory when transforming from the OO-language with automatic garbage collection where the programmer will have had no thought about memory management and object owership to C++. – Flipbed Mar 05 '15 at 12:15
  • 1
    Right, so you're prematurely optimizing. Forget about `shared_ptr` here, because if you want the maximum performance you aren't going to get it this way. See `boost::shared_array` or `boost::scoped_array` or `std::unique_ptr`. – John Zwinck Mar 05 '15 at 12:17
  • Thanks! I will take a look at unique_ptr. I am trying to avoid external libraries such as boost since it may not be supported on some embedded systems. – Flipbed Mar 05 '15 at 12:21
0

make_shared does not support non-explicit initializer lists. You could make use of the fact that auto can deduce an initializer list:

auto init = { 6, 4, 9 };
auto vec = std::make_shared<std::vector<int>>(init); 

But as others have pointed out, you need to consider if you need a shared_ptr at all, vector manages its own memory. shared_ptr is not free.

Chris Drew
  • 14,926
  • 3
  • 34
  • 54