[Bug c++/9937] [DR 176] Base class template name is not injected properly into derived class

widman at gimpel dot com gcc-bugzilla@gcc.gnu.org
Thu Jul 3 01:40:00 GMT 2008



------- Comment #7 from widman at gimpel dot com  2008-07-03 01:40 -------
(In reply to comment #3)

Hi all,

I happen to be looking at something related to this issue and encountered this
GCC bug, so I thought I'd offer my observations.

>  bangerth@dealii.org wrote:
<snip>
>  |     Something seems indeed inconsistent. Your access in struct Z
>  |     is bogus, but this is an extract:
>  
>  I don't think so.
>  
>  ~From ISO/IEC 14882
>  
>  14.6/2a
>  
>  "The injected-class-name of a class template or class template
>  specialization can be used either with or without
>  a template-argument-list wherever it is in scope. [Example:
>  
>  template <class T> struct Base {
>  ~  Base* p;
>  };
>  
>  template <class T> struct Derived: public Base<T> {
>  ~  typename Derived::Base* p; // meaning Derived::Base<T>
>  };
>   end example ]"
>  
>  So if B<int> is in scope B is as well.

True.  I think ISO/IEC 14882:2003, 14.6.1 [temp.local] indicates pretty clearly
what's supposed to happen here:  within Y and Z, 'B' is in scope as the
injected-class-name of the base class.  But that injected-class-name is only
taken as a template-name if it's immediately followed by the '<' token;
otherwise it's an alias to the class of which it's a member.

For what it's worth, I can confirm that the EDG front end appears to have had
this correctly implemented for many years now in "strict mode" (that is, the
mode where they don't try to emulate anyone's bugs).

I ran into this bug with the following test case:

template <class T> 
struct B  {
    static void j();
};

namespace N {
    template <class T> 
        struct B { 
            static void j();
        }; 

}

template <class T> 
struct A : public N::B<T> { 
    static void f1 ( ) { 
        A::template B<T>::j(); // ok 
        A::B::j(); // ok
    } 
    static void f2 ( ) { 
        B<T>::j(); // ok
    } 
}; 


void h() {
    A<int>::f1(); // calls ::N::B<int>::j() twice
    A<int>::f2(); // calls ::B<int>::j() once
}

With this I currently get:

g++-mp-4.4 (GCC) 4.4.0 20080620 (experimental)
g2.cpp: In static member function 'static void A<T>::f1() [with T = int]':
g2.cpp:27:   instantiated from here
g2.cpp:17: error: no class template named 'B' in 'struct A<int>'
g2.cpp:18: error: no type named 'B' in 'struct A<int>'


-- 

widman at gimpel dot com changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |widman at gimpel dot com


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=9937



More information about the Gcc-bugs mailing list