the code:
class Global
{
public:
static const char *name() {return "Global";}
};
typedef Global T_Outter;
class Outter
{
public:
typedef T_Outter O_Outter; // <= <1>
typedef Outter T_Outter; // <= <2>
static const char *name() {return "Outter";}
static void test() {printf("self: %s, outter: %s\n", name(), O_Outter::name());}
class Inner
{
public:
typedef T_Outter O_Outter;
typedef Inner T_Outter;
static const char *name() {return "Inner";}
static void test() {printf("self: %s, outter: %s\n", name(), O_Outter::name());}
};
};
Outter::test();
Outter::Inner::test();
// output:
// self: Outter, outter: Global
// self: Inner, outter: Outter
what I want to do:
typedef
s would be generated by macros, with the tricks, there's no need to manually "bind" Outter
and Inner
's relationship, it's done by typedef
automaticallyhere's the question:
<1>
and <2>
with same T_Outter
nameOutter::O_Outter
equals to Global
Outter::Inner:O_Outter
equals to Outter
It is not allowed to change meaning of a global name inside a class after it was used unqualified in the class definition. The program is ill-formed, NDR.
A name
N
used in a classS
shall refer to the same declaration in its context and when re-evaluated in the completed scope ofS
. No diagnostic is required for a violation of this rule.
Live demo with GCC 10:
error: declaration of 'typedef class Outter Outter::T_Outter' changes meaning of 'T_Outter' [-fpermissive]
A possible workaround is to qualify it:
class Outter {
public:
typedef ::T_Outter O_Outter;
typedef Outter T_Outter; // OK
. . .