2

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?

Dmitry Kuzminov
  • 6,180
  • 6
  • 18
  • 40
  • gcc is right. So is clang, because a diagnostic is not required. And you don't have to use `ns::` explicitly. Just `using Utility = ::Utility;` works. – cigien Aug 29 '20 at 12:31
  • @cigien [a relatively recent similar question](https://stackoverflow.com/questions/61455507/hiding-names-with-using-directive) was answered as that it is gcc's bug and people seem to like the answer :/ – Language Lawyer Aug 29 '20 at 12:55
  • @LanguageLawyer Well, that's annoying. I wonder what the protocol is for completely opposite answers to basically the same question. Merging seems weird. I assume that given this [discussion](https://stackoverflow.com/questions/63369264/is-a-nested-alias-template-that-redeclares-the-same-name-valid) we had, you disagree with the answer below. – cigien Aug 29 '20 at 13:03
  • 1
    @cigien: Using `using Utility = ::Utility;` doesn't work, you have to specify the namespace as well. – Dmitry Kuzminov Aug 29 '20 at 16:40

0 Answers0