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 the WP at the June, 2008 meeting.]
13.8 [temp.res] paragraphs 2 and 4 read,
A name used in a template declaration or definition and that isdependent on atemplate-parameter is assumed not to name a type unlessthe applicable name lookup finds a type name or the name is qualifiedby the keywordtypename.
If a specialization of a template is instantiated for a set oftemplate-arguments such that thequalified-id prefixedbytypename does not denote a type, the specialization isill-formed.
It is not clear whether this is intended to, or is sufficient to,render a specialization ill-formed if a dependentqualified-idthat isnot prefixed bytypename actuallydoesdenote a type. For example,
int i; template <class T> void f() { T::x * i; // declaration or multiplication!? } struct Foo { typedef int x; }; struct Bar { static int const x = 5; }; int main() { f<Bar>(); // multiplication f<Foo>(); // declaration! }I think that the specialization forFoo should beill-formed.
Proposed resolution (February, 2008):
Add the following after 13.8 [temp.res] paragraph 5:
If, for a given set of template arguments, a specialization of a templateis instantiated that refers to aqualified-id that denotes a type,and thenested-name-specifier of thequalified-id dependson a template parameter, thequalified-id shall either be prefixedbytypename or shall be used in a context in which it implicitlynames a type as described above. [Example:
template <class T> void f(int i) { T::x * i; //T::x must not be a type } struct Foo { typedef int x; }; struct Bar { static int const x = 5; }; int main() { f<Bar>(1); // OK f<Foo>(1); // error:Foo::x is a type }—end example]