Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why std::make_shared has to be provided type info but std::make_pair doesn't have to?

Tags:

c++

For example, when we want to create a std::pair, we can simply call:

std::make_pair(5, "foo");

But when we intend to create a shared_ptr, we have to provide type info:

std::make_shared<Foo>("Boo", 1024);

Is there any reason that makes them different?

like image 864
AhSeng Fan Avatar asked Sep 22 '15 18:09

AhSeng Fan


People also ask

What is std :: Make_shared?

std::make_sharedAllocates and constructs an object of type T passing args to its constructor, and returns an object of type shared_ptr<T> that owns and stores a pointer to it (with a use count of 1). This function uses ::new to allocate storage for the object.

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.

Does Make_shared call copy constructor?

Its seesm straight-forward -- make_shared needs to copy/move the unnamed MyClass() temp you created explicitly into the shared object space it allocates. It uses the move constructor if it can, or the copy constructor if there is no move constructor. What do you expect to happen?


2 Answers

The function std::make_pair<T1, T2> creates a pair std::pair<T1, T2> where the types T1 and T2 are the types of arguments of the function. As such they can be deduced by the compiler and normally you do not need to provide them explicitly.

The function std::make_shared<T> creates a new object of type T and returns shared_ptr<T> storing this object. The function passes all its arguments to the constructor of T. There is no way for the compiler to deduce the type T from the arguments. Even if the argument is e.g. const T& the compiler cannot know if you want to create shared_ptr<T> or shared_ptr<SomeOtherTypeWithConstructorAcceptingT>.

like image 133
Wojtek Surowka Avatar answered Oct 01 '22 01:10

Wojtek Surowka


std::make_shared should be called emplace_shared -- it calls an arbitrary ctor.

make_pair constructs a copy or move of its types.

They have different purposes: one is for type deduction help, the other for emplace construction. They are both factories, hence the make name.

like image 38
Yakk - Adam Nevraumont Avatar answered Oct 01 '22 02:10

Yakk - Adam Nevraumont