Doot
Doot

Reputation: 745

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

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?

Upvotes: 1

Views: 132

Answers (1)

463035818_is_not_an_ai
463035818_is_not_an_ai

Reputation: 122575

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).

Upvotes: 6

Related Questions