This is an unofficial snapshot of the ISO/IEC JTC1 SC22 WG21 Core Issues List revision 119a. See http://www.open-std.org/jtc1/sc22/wg21/ for the official list.
2025-12-20
[Voted into WP at March 2004 meeting.]
Issue 1:
The working paper is not clear about how the typename/template keywordsinteract with using-declarations:
template<class T> struct A { typedef int X; }; template<class T> void f() { typename A<T>::X a; // OK using typename A<T>::X; // OK typename X b; // ill-formed; X must be qualified X c; // is this OK? }When the rules fortypename and the similar use oftemplatewere decided, we chose to require that they be used at every reference.The way to avoidtypename at every use is to declare a typedef;then the typedef name itself is known to be a type. Forusing-declarations,we decided that they do not introduce new declarations but rather are aliasesfor existing declarations, like symbolic links. This makes it unclear whetherthe declaration "X c;" above should be well-formed, because thereis no new name declared so there is no declaration with a "this is a type"attribute. (The same problem would occur with thetemplate keywordwhen a member template of a dependent class is used). I think these arethe main options:The core WG already resolved this issue according to (1), but the wordingdoes not seem to have been added to the standard. New wording needs tobe drafted.
Issue 2:
Either way, one more point needs clarification. If the first optionis adopted:
template<class T> struct A { struct X { }; }; template<class T> void g() { using typename A<T>::X; X c; // if this is OK, then X by itself is a type int X; // is this OK? }When "g" is instantiated, the two declarations ofX are compatible(9.10 [namespace.udecl] paragraph 10).But there is no way to know this when the definition of "g" iscompiled. I think this case should be ill-formed under the first option.(It cannot happen under the second option.) If the second option is adopted: template<class T> struct A { struct X { }; }; template<class T> void g() { using A<T>::X; int X; // is this OK? }Again, the instantiation would work but there is no way to know that inthe template definition. I think this case should be ill-formed under thesecond option. (It would already be ill-formed under the first option.)From John Spicer:
The "not a new declaration" decision is more of a guiding principlethan a hard and fast rule. For example, a name introduced in ausing-declarationcan have different access than the original declaration.Tentative Resolution:Like symbolic links, ausing-declaration can be viewed as a declarationthat declares an alias to another name, much like a typedef.
In my opinion, "X c;" is already well-formed. Why would we permittypename to be used in ausing-declaration if not to permit thisprecise usage?
In my opinion, all that needs to be done is to clarify that the "typeness"or "templateness" attribute of the name referenced in theusing-declarationis attached to the alias created by theusing-declaration. This issolution #1.
The rules for multiple declarations with the same name in the same scopeshould treat ausing-declaration which names a type as a typedef,just as a typedef of a class name is treated as a class declaration. Thisneeds drafting work. Also seeCore issue 36.
Rationale (04/99): Any semantics associated with thetypename keyword inusing-declarations should be considered anextension.
Notes from the April 2003 meeting:
This was reopened because we are now considering extensions again.We agreed that it is desirable for the typename to be "sticky" ona using-declaration, i.e., references to the name introduced bythe using-declaration are known to be type names without the useof the typename keyword (which can't be specified on an unqualifiedname anyway, as of now). The related issue with the template keywordalready has a separate issue109.
Issue 2 deals with the "struct hack."There is an example in 9.10 [namespace.udecl] paragraph 10that shows a use of using-declarations to import two names thatcoexist because of the "struct hack." After some deliberation,we decided that the template-dependent using-declaration case isdifferent enough that we did not have to support the "struct hack"in that case.A name introduced in such a case is like a typedef, and no otherhidden type can be accessed through an elaborated type specifier.
Proposed resolution (April 2003, revised October 2003):
Add a new paragraph to the bottom of 9.10 [namespace.udecl]:
If ausing-declaration usesthe keywordtypename and specifies a dependent name(13.8.3 [temp.dep]), thename introduced by theusing-declaration is treated as atypedef-name (9.2.4 [dcl.typedef]).