So when I have code like:
shared_ptr<Foo> bar (my_normal_operator<Foo>(mumble));
Even though the type Foo is coming out of left field, it works as the return type is produced solely through an “additive” pattern to what is given:
template <typename Target, typename Source>
shared_ptr<Target> my_normal_operator(Source src)
{
/* ... whatever ... */
}
But what if the situation instead looked something like this:
shared_ptr<Foo> bar (my_pointer_operator<Foo*>(mumble));
It needs some way to pull the pointer off the type. I dug around and found std::remove_pointer, but a naive application gives a “type/value mismatch”:
template <typename Target, typename Source>
shared_ptr< std::remove_pointer<Target>::type > my_pointer_operator(Source src)
{
/* ... whatever ... */
}
I didn’t actually expect it to work…but I’m putting it here as an expression of the what-I’m-looking for intent!
Sigh. Every time I step into any new territory with templates and traits I feel like one of those “I have no idea what I’m doing” meme animals. :-/
You need
typename:Because the type of
std::remove_pointer<Target>::typedepends on a template argument.Personally, I would leave
TargetasFooand within the definition ofmy_pointer_operatorusetypename std::add_pointer<Target>::type, so the caller can specify the return value more directly. The function name gives away the difference in implementation.