------- Comment #2 from schaub-johannes at web dot de  2010-06-03 16:45 -------
The Standard allows this at 9.2/13a ("In addition, if class T has a
user-declared constructor (12.1), every nonstatic data member of class T shall
have a name different from T."). In our case we don't have a user declared
constructor. 

Now we have an object name, and a class-name. The object name should hide the
class name according to 3.3.7/2. You can access the class name by using an
elaborated type specifier "class X::X" (which is not replaced by a constructor
reference either) or if you name it in a base-specifier "struct Y : X::X { };". 

C++0x adds using declarations as one further context looking up the the
*constructor* specifically (not by way of injected class names). Thus the
following names the constructors of X (but inherits no constructors):

struct Y : X { using X::X; };

It does not name the data-member "X", because the mapping from "X::X" is done
by syntactical means by the second bullet of 3.4.3.1/2. The same mapping makes
the following work in C++0x:

struct Y : X { using identity<X>::type::type; };

This shows it doesn't use the injected class name of "X" for looking up
constructors. Now, the following is valid in C++03 and C++0x:

struct Y : X { using identity<X>::type::X; };

In C++03 this is a normal using declaration that redeclares the member name to
be public in Y and which resolves to the data member. In C++0x,
3.4.3.1/1bullet4 (see DR #400) makes the lookup yield both the injected class
name and the data member (personally i always thought that a lookup can only
yield multiple declarations if all the declarations are function names, but i'm
always surprised again). 

Anyway, if in C++0x it yields both the injected class name and the data member,
should this be the *final* result, or is that result still subject of 3.4.3.1/2
making it name only the constructor? I think this is important to clarify,
since it determines the validity of the following:

struct A { private: int A; };
struct B : A { public: using A::A; };
void f() { B b; b.A; };

If "using A::A;" names the injected class name and the data member of A, this
code seems to be valid, because "A" is public as a member of B. However if we
are subjectof 3.4.3.1/2, we will have "using A::A" name the constructors of A
and thus be a no-op declaration (no constructors are inherited in this case.
And since the data member lookup result was discared, no member name is
redeclared).

Any ideas? Are there issue reports about it, or am i just missing something?


-- 


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

Reply via email to