Here is my code:
namespace ns {
template<typename T>
struct Utility {
};
struct Concrete {
using Utility = Utility<Concrete>;
};
}
I have a template class ns::Utility
and a class ns::Concrete
that specifies the class for the utility: ns::Concrete::Utility
. Now it should be possible to use the utilities that the concrete classes specialize for themselves.
That works for MSVC, but the GCC produces an error:
error: declaration of ‘using Utility = struct ns::Utility’ [-fpermissive] using Utility = Utility;
error: changes meaning of ‘Utility’ from ‘struct ns::Utility’ [-fpermissive]
To fix that I can specify the namespace explicitly disambiguing the ns::Concrete::Utility
and ns::Utility
:
namespace ns {
template<typename T>
struct Utility {
};
struct Concrete {
using Utility = ns::Utility<Concrete>;
};
}
But actually I don't see neither ambiguity nor any other problem in my initial code that should make the compiler complaining. I don't want to specify explicitly the full class name with the namespace as well: that makes the code less flexible (for example, what if I decide to rename the namespace?)
What does the standard say, and should my code be considered as an error?
Update: The advice to use using Utility = ::Utility<Concrete>;
doesn't work (as there could be both ::Utility
and ns::Utility
), and I still have to fully specify the type including namespace. So I can agree that g++ tries to avoid the case when both definitions are used in the same class, before and after using
/typedef
, but the need to fully specify the class name is very annoying. Moreover, even if I specify the full name, g++ has to produce an error in this case:
struct Concrete {
Utility<int> u1;
using Utility = ns::Utility<Concrete>;
Utility u2;
};
Why does it care of a valid redefinition where I don't use both Concrete::Utility
and ns::Utility
in the same scope using the same Utility
name?