Dimitri Schachmann Dimitri Schachmann - 2 months ago 4
C++ Question

Is there a way to match a nested template type implicitly in C++?

I have the following MWE:

#include <iostream>
#include <memory>

class A {
int n = 42;
typedef std::shared_ptr<A> Ptr;

template<typename T>
void foo(typename T::Ptr arg) {
std::cout << arg->n << std::endl;

template<typename T>
void bar(T arg) {
std::cout << arg.n << std::endl;

int main() {
A::Ptr a = A::Ptr(new A());
foo<A>(a); // Can I avoid giving <A> here explicitly.
// foo(a); // does not compile
bar(*a); // after all this does work
return 0;

To me it looks like it should also be possible to call
instead of
. Why is this not possible and can I somehow change the definition of
to make this possible?

I realize that I could just skip the
in the signature, but I still want to have access to the
type without the pointer.


That is not possible because that is non-deducible context.

The type of a is just std::shared_ptr<A>, which means if foo(a) works, then the following should also work:

std::shared_ptr<A> x(new A());

If so, then what should T be deduced to — and why? You might be tempted to say "T should be deduced to A, because A has a nested type Ptr which is same as std::shared_ptr<A>". Well, what if there is another class defined as:

struct B
    typedef std::shared_ptr<A> Ptr;

What should T be deduced to? A or B? or something else?

Here is another topic that discusses non-deducible context using a different example:

Hope that helps.