Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

using c++ aggregate initialization in std::make_shared

Tags:

c++

c++11

Per my understanding, the following code constructs an object of type Foo and then moves that object into the memory allocated by std::make_shared

struct Foo {     std::string s;     int i;     char c; };  int main(int argc, char* argv[]) {     auto foo = std::make_shared<Foo>(Foo{"hello", 5, 'c' }); } 

Is it possible to aggregate initialize Foo directly into the memory allocated by std::make_shared?

like image 258
tcb Avatar asked Feb 09 '16 18:02

tcb


People also ask

What is aggregate initialization in C++?

An aggregate type is a structure, union, or array type. If an aggregate type contains members of aggregate types, the initialization rules apply recursively.

What does Make_shared return in C++?

It constructs an object of type T passing args to its constructor, and returns an object of type shared_ptr that owns and stores a pointer to it.

Does Make_shared throw?

So, if you throw exception from your class' constructor, then std::make_shared will throw it too. Besides exceptions thrown from constructor, std::make_shared could throw std::bad_alloc exception on its own.


1 Answers

You could create an adapter with a variadic constructor template to forward the arguments, something like:

template<class T> struct aggregate_adapter : public T {     template<class... Args>     aggregate_adapter(Args&&... args) : T{ std::forward<Args>(args)... } {} }; 

And then you can do:

auto foo = std::make_shared<aggregate_adapter<Foo>>("hello", 5, 'c'); 

Since aggregate_adapter<Foo> and Foo are related, foo is convertible to std::shared_ptr<Foo> as well.

Caveats


Unfortunately, the use of forwarding also makes it impossible to brace-init any of the members like std::make_shared<aggregate_adapter<Foo>>({'h','e','l','l','o'}, 5, 'c'); without specifying the type explicitly, but the same restriction applies to make_shared already.

like image 88
melak47 Avatar answered Sep 19 '22 11:09

melak47