typedef changes meaning

前端 未结 2 855
失恋的感觉
失恋的感觉 2020-11-29 10:07

When I compile the following snippet with g++

template
class A
{};

template
class B
{
    public:
        typedef         


        
相关标签:
2条回答
  • 2020-11-29 10:51

    g++ is correct and conforming to the standard. From [3.3.7/1]:

    A name N used in a class S shall refer to the same declaration in its context and when re-evaluated in the completed scope of S. No diagnostic is required for a violation of this rule.

    Before the typedef, A referred to the ::A, however by using the typedef, you now make A refer to the typedef which is prohibited. However, since no diagnostic is required, clang is also standard conforming.

    jogojapan's comment explains the reason for this rule. Take the following change to your code:

    template<class T>
    class A
    {};
    
    template<class T>
    class B
    {
        public:
            A a; // <-- What "A" is this referring to?
            typedef     A<T>            A;
    };
    

    Because of how class scope works, A a; becomes ambiguous.

    0 讨论(0)
  • 2020-11-29 10:59

    I will add to Jesse's answer about the seemingly peculiar behavior of GCC in compiling:

    typedef A<T> A;
    

    vs

    typedef ::A<T> A;
    

    This also applies to using statements as well of the form:

    using A =   A<T>;
    using A = ::A<T>;
    

    What seems to be happening within GCC, is that during the compilation of the typedef/using statement declaring B::A, that the symbol B::A becomes a valid candidate within the using statement itself. I.e. when saying using A = A<T>; or typedef A<T> A; GCC considers both ::A and B::A valid candidates for A<T>.

    This seems odd behavior because as your question implies, you don't expect the new alias A to become a valid candidate within the typedef itself, but as Jesse's answer also says, anything declared within a class becomes visible to everything else inside the class - and in this case apparently even the declaration itself. This type of behavior may be implemented this way to permit recursive type definitions.

    The solution as you found is to specify for GCC precisely which A you're referring to within the typedef and then it no longer complains.

    0 讨论(0)
提交回复
热议问题