Amin Gholizad
Amin Gholizad

Reputation: 71

How to get the namespace of a template class?

I want to write a template class like:

template<class A>
class B{/*class B code*/};

there are class A is in various namespaces like:

namespace ns1{
class X{/*class X code*/};
class A{/*class A code*/};
}
namespace ns2{
class X{/*class X code*/};
class A{/*class A code*/};
}

Now how to access class X in the same namespace as A somewhere inside B?

Upvotes: 3

Views: 862

Answers (1)

Nicol Bolas
Nicol Bolas

Reputation: 473232

Now how to access class X in the same namespace as A somewhere inside B?

You don't. There's no way to take a type, extract its namespace, and build a new typename by combining that namespace and a name.

If you need the B template to be able to access some class that is associated with a type given by the template parameter, then that association ought to be explicit, a part of the interface of the type in some way, not based on arbitrary naming conventions.

The two traditional mechanisms to specify this sort of thing are a member type alias or a traits class:

//Member alias
template<class A>
class B{
  /* typename A::X is required to be an alias for the class associated with `A`.
};

namespace ns1{
class U{/*class U code*/};
class A{ using X = U;};
}

//traits
//Default implementation
template<class A>
class A_traits
{
  using X = typename A::X; //By default, assume that `A` provides a member typedef.
};

template<class A>
class B{
  /* typename A_traits<A>::X is required to be an alias for the class associated with `A`.
};

namespace ns1{
class U{/*class U code*/};
class A{}; //Doesn't provide the default.
}

//Specialization for `ns1::A`. Must be declared in the same namespace as the primary `A_traits` namespace
template<>
class A_traits<ns1::A>
{
  using X == ns1::U;
};

The traits mechanism is more complicated, but it works with types that you don't control as well as fundamental types like int and pointers.

Upvotes: 3

Related Questions