Title
Ambiguous wording on naming a type in deduction
Status
cd1
Section
13.10.3 [temp.deduct]
Submitter
Daveed Vandevoorde

Created on 2003-01-16.00:00:00 last changed 161 months ago

Messages

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):

In 13.10.3 [temp.deduct], paragraph 2, bullet 3, sub-bullet 3, replace

Attempting to use a type in the qualifier portion of a qualified name that names a type when that type does not contain the specified member, or if the specified member is not a type where a type is required.

With

Attempting to use a type in a nested-name-specifier of a qualified-id when that type does not contain the specified member, or
  • the specified member is not a type where a type is required, or
  • the specified member is not a template where a template is required, or
  • the specified member is not a nontype where a nontype is required.

[Example:

Replace the example that follows the above text with

template <int I> struct X { };
template <template <class T> class> struct Z {};
template <class T> void f(typename T::Y*){}
template <class T> void g(X<T::N>*){}
template <class T> void h(Z<T::template TT>*){}
struct A {};
struct B { int Y; };
struct C {
	typedef int N;
};
struct D {
	typedef int TT;
};

int main()
{
	// Deduction fails in each of these cases:
	f<A>(0); // A does not contain a member Y
	f<B>(0); // The Y member of B is not a type
	g<C>(0); // The N member of C is not a nontype
	h<D>(0); // The TT member of D is not a template
}
]
Date: 2003-04-15.00:00:00

Notes from April 2003 meeting:

We agreed that the example should be valid. The phrase "that names a type" applies to "the qualifier portion."

Date: 2004-09-10.00:00:00

The following example (simplified from a posting to comp.lang.c++.moderated) is accepted by some compilers (e.g., EDG), but not by other (e.g., g++).

  struct S {
    static int const I = 42;
  };

  template<int N> struct X {};

  template<typename T> void f(X<T::I>*) {}

  template<typename T> void f(X<T::J>*) {}

  int main() {
    f<S>(0);
  }

The wording in the standard that normally would cover this (third sub-bullet in 13.10.3 [temp.deduct] paragraph 2) says:

Attempting to use a type in the qualifier portion of a qualified name that names a type when that type does not contain the specified member, or if the specified member is not a type where a type is required.
(emphasis mine). If the phrase "that names a type" applies to "a qualified name," then the example is invalid. If it applies to "the qualifier portion," then it is valid (because the second candidate is simply discarded).

I suspect we want this example to work. Either way, I believe the sub-bullet deserves clarification.

History
Date User Action Args
2008-10-05 00:00:00adminsetstatus: wp -> cd1
2004-04-09 00:00:00adminsetmessages: + msg1027
2004-04-09 00:00:00adminsetstatus: ready -> wp
2003-11-15 00:00:00adminsetstatus: review -> ready
2003-04-25 00:00:00adminsetmessages: + msg835
2003-04-25 00:00:00adminsetmessages: + msg834
2003-04-25 00:00:00adminsetstatus: open -> review
2003-01-16 00:00:00admincreate