ChronoTrigger
ChronoTrigger

Reputation: 8617

Correct syntax for partial specialization with smart pointers

I have this function

template<class A, class B>
std::shared_ptr<A> Foo(const B& obj) { ... }

And I want to provide a convenient function that also gets smart pointer (shared_ptr or unique_ptr) instead of references. Something like this:

template<class A, class B>
std::shared_ptr<A> Foo(const std::shared_ptr<B>& obj) {
  return Foo<A>(const_cast<const B&>(*obj));
}

It only works like that if I overload Foo to get shared_ptr as a parameter. However, I want to write it as a partial specialization. I also tried

template<class A>
template<class B>
std::shared_ptr<A> Foo(const std::shared_ptr<B>& obj) { ... }

What is the correct syntax for this partial specialization?

Upvotes: 1

Views: 635

Answers (1)

Piotr Skotnicki
Piotr Skotnicki

Reputation: 48487

You cannot partially specialize a function template. However, you can safely rely on your current solution. Having two function overloads:

template<class A, class B>
std::shared_ptr<A> Foo(const B& obj);

template<class A, class B>
std::shared_ptr<A> Foo(const std::shared_ptr<B>& obj);

the latter is considered by the compiler as more specialized * in overload resolution due to partial ordering, hence, it gets picked whenever a matching std::shared_ptr<T> is passed in as an argument.


* const std::shared_ptr<B>& is more specialized than const B&, because for some unique type Unique, B in const B& can be deduced from const std::shared_ptr<Unique>&, but in a counter scenario, for a const std::shared_ptr<B>& parameter with a const Unique& argument deduction of B fails.

Upvotes: 1

Related Questions