Can a 'using' be made in a class independent of the class' template?

Issue

If I use a typedef or using inside a class or struct, I sometimes want it to be independent of the templates used for that class or struct.

In the example below, I would use Object<T>::RefCountT, which would work, but I would rather use something like Object::RefCountT in this case, because then I don’t have to arbitrarily pick a type (which may be confusing when read).

template <typename T>
struct Object {
    using RefCountT = unsigned short; // This is independent of T
};

To me, the obvious (but not ideal) solution would be to just define it outside of the class, like

using ObjectRefCountT = unsigned short;

I also attempted to make a redefinition with no templates, assuming that they would not be considered the same, but this caused the expected error about redefinition.

I’m assuming that since it’s a class not a function, I can’t do it implicitly and how would the compiler know that it doesn’t matter here?

Solution

Object is just a template, but you need to instantiate it to access its member alias. I see several options:

A) Don’t make RefCountT a member of Object.

B) Provide a default parameter so you need not explicitly pick a type to access the alias:

template <typename T = void>
struct Object {
    using RefCountT = unsigned short; // This is independent of T
};

then

Object<>::RefCount x;

C) Use a common base class for all instantiations:

struct ObjectBase {
    using RefCountT = unsigned short;
};

template <typename T>
struct Object : ObjectBase {
    using ObjectBase::RefCountT;
};

then

ObjectBase::RefCountT x;

In general it can be benefical to have anything that does not depend on the template parameter T not inside the template. Note that for example

template <>
struct Object<int> : ObjectBase {};

Is a specialization that has nothing in common with the general declaration of Object (ie no member alias). You would have to repeat everything in the specialization, unless you move it to the ObjectBase. Hence I would suggest A) or C).

Answered By – 463035818_is_not_a_number

Answer Checked By – Timothy Miller (AngularFixing Admin)

Leave a Reply

Your email address will not be published.