c++template-argument-deductionmake-shared

Why the compiler cannot deduce the template arguments from std::make_shared?


I have this simple question from an exercise in "C++ primer, 5th ed":

Exercise 16.38: When we call make_shared (§ 12.1.1, p. 451), we have to provide an explicit template argument. Explain why that argument is needed and how it is used.

I've tried, then I've seen some answers and suggestions, but I'm not convinced yet.

Some said:

The argument is probably need for the return type which cannot be deduced from the arguments supplied in the function call (i.e. make_shared<int> returns a shared_ptr<int>).

Alternatively the function body of make_shared needs to know what type to allocate to dynamic memory which is not deducible from the arguments supplied.

But I've tried this code on my own:

template <typename T>
std::vector<T> make_vec(T x...)
{
    return std::vector<T>(x);
}

int main()
{
   auto vi = make_vec(77);
   std::cout << vi.size() << std::endl;
}

As you can see, my make_vec works without explicit template arguments, while make_shared() cannot. Why is that?


Solution

  • For most variants of std::make_shared which return a std::shared_ptr<T> or std::shared_ptr<U[]> - no parameter has type T. Examples:

    template< class T, class... Args >
    shared_ptr<T> make_shared( Args&&... args );
    template<class T>
    shared_ptr<T> make_shared( std::size_t N );
    

    (where in the latter example, T must be U[] for some U).

    Without a type-T parameter to those functions - how can you deduce T (or U)?

    In your example, you do take a parameter of type T and can easily deduce the template argument.