Следующий код
#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;
}
НЕ скомпилирован GNU-g++ 4.9.2
, а clang 3.5.0
и ведет себя так, как я пытался объяснить во встроенных комментариях, и как это видно из полученного вывода. Это ошибка в компиляторе GNU? Диагностика говорит, что строка typedef int A;
в области struct B
ошибка: изменяет значение «A» с «typedef double A»
Обратите внимание, что когда иерархия не состоит из template
(и, конечно, объявление Z c{36};
удалено), поиск, выполненный clang
в области C
(правильно, как я полагаю), находит typedef
в области B
и рассматривает член a
быть типа int
; то выдает предупреждение об сужении инициализирующей double
константы 2.2
...