Using-declarations and the "struct hack"
Section [namespace.qual]
Mark Mitchell

Created on 2003-01-22.00:00:00 last changed 162 months ago


Date: 2004-03-15.00:00:00

[Voted into WP at March 2004 meeting.]

Date: 2003-10-15.00:00:00

Proposed resolution (October 2003):

Add a bullet to the end of [class.qual] paragraph 1:

  • the lookup for a name specified in a using-declaration (9.9 [namespace.udecl]) also finds class or enumeration names hidden within the same scope (_N4868_.6.4.10 [basic.scope.hiding]).

Change the beginning of 9.9 [namespace.udecl] paragraph 4 from

A using-declaration used as a member-declaration shall refer to a member of a base class of the class being defined, shall refer to a member of an anonymous union that is a member of a base class of the class being defined, or shall refer to an enumerator for an enumeration type that is a member of a base class of the class being defined.


In a using-declaration used as a member-declaration, the nested-name-specifier shall name a base class of the class being defined. Such a using-declaration introduces the set of declarations found by member name lookup (6.5.2 [class.member.lookup], [class.qual]).
Date: 2003-04-15.00:00:00

Notes from April 2003 meeting:

This is related to issue 11. 9.9 [namespace.udecl] paragraph 10 has an example for namespaces.

Date: 2003-01-22.00:00:00

Consider this code:

  struct A { int i; struct i {}; };
  struct B { int i; struct i {}; };
  struct D : public A, public B { using A::i; void f (); };
  void D::f () { struct i x; }

I can't find anything in the standard that says definitively what this means. 9.9 [namespace.udecl] says that a using-declaration shall name "a member of a base class" -- but here we have two members, the data member A::i and the class A::i.

Personally, I'd find it more attractive if this code did not work. I'd like "using A::i" to mean "lookup A::i in the usual way and bind B::i to that", which would mean that while "i = 3" would be valid in D::f, "struct i x" would not be. However, if there were no A::i data member, then "A::i" would find the struct and the code in D::f would be valid.

John Spicer: I agree with you, but unfortunately the standard committee did not.

I remembered that this was discussed by the committee and that a resolution was adopted that was different than what I hoped for, but I had a hard time finding definitive wording in the standard.

I went back though my records and found the paper that proposed a resolution and the associated committee motion that adopted the proposed resolution The paper is N0905, and "option 1" from that paper was adopted at the Stockholm meeting in July of 1996. The resolution is that "using A::i" brings in everything named i from A. [namespace.qual] paragraph 2 was modified to implement this resolution, but interestingly that only covers the namespace case and not the class case. I think the class case was overlooked when the wording was drafted. A core issue should be opened to make sure the class case is handled properly.

Date User Action Args
2008-10-05 00:00:00adminsetstatus: wp -> cd1
2004-04-09 00:00:00adminsetmessages: + msg1002
2004-04-09 00:00:00adminsetstatus: ready -> wp
2003-11-15 00:00:00adminsetstatus: review -> ready
2003-04-25 00:00:00adminsetmessages: + msg813
2003-04-25 00:00:00adminsetmessages: + msg812
2003-04-25 00:00:00adminsetstatus: open -> review
2003-01-22 00:00:00admincreate