The following code
#include <iostream>
typedef double A; // a global typedef
template <class Z> struct B // a template class...
{
A i{22.2}; // global typedef is in scope
typedef int A; // now a local typedef with the same name is introduced
A b{24}; // now the local typedef is in scope
Z c{36}; // a simple member of the template type
};
template <class Z> struct C : B<Z> // a template struct inheriting B
{
A a; // global typedef is in scope because we are in a template struct
C( ) : a(2.2){ }
};
int main( )
{
C<int> c;
std::cout << "c's members: "
<< c.a << ' '
<< c.i << ' '
<< c.b << ' '
<< c.c << std::endl;
std::cout << "their sizeof: "
<< sizeof(c.a) << ' '
<< sizeof(c.i) << ' '
<< sizeof(c.b) << ' '
<< sizeof(c.c) << std::endl;
}
is NOT compiled by GNU-g++ 4.9.2
while it is by clang 3.5.0
and behaves as I tried to explain in the embedded comments and as it can be seen by the output produced. Is this a bug in the GNU compiler?
The diagnostic says that the line typedef int A;
in the scope of the
struct B
error: changes meaning of ‘A’ from ‘typedef double A’
Note that when the hierarchy is not made of template
(and of course the Z c{36};
declaration is removed) the lookup performed by clang
in the scope of C
(correctly, as I suppose) finds the typedef
in the scope of B
and considers the member a
to be of
type int
; then it issues a warning about the narrowing of the initializing double
constant 2.2
...