Let's say I have a templated base class, and a templated class that derives from it:
template <typename T>
class Base {};
template <typename T>
class Derived : public Base<T> {};
Further, I've got a function that wants to accept a shared pointer to any Base<T>
or subclass, and be able to easily use the T
parameter as part of its signature:
template <typename T>
T DoSomething(std::shared_ptr<Base<T>>);
I want to be able to call it, with a deduced T
, with shared pointers to Base<T>
or anything that derives from it:
DoSomething(std::make_shared<Base<T>>());
DoSomething(std::make_shared<Derived<T>>());
Of course the latter doesn't work, because type deduction fails.
How can I modify the signature of DoSomething
to allow it to work? I've seen plenty of answers in the case where Base
and Derived
aren't templates, but I'm not sure how to do it if I still want to deduce T
(for example to use it as a return type, as above).
Ideally this would fail for shared pointers to non-derived inputs (and non-shared pointers) at overload resolution time.
You can use a template template parameter in your function, then a
static_assert
to enforce your requirement.Edit
If
DoSomething
is overloaded we can use SFINAE to disable it instead of thestatic_assert
. That would look as follows.