Title
Template argument deduction for conversion functions and qualification conversions
Status
cd1
Section
13.10.3.4 [temp.deduct.conv]
Submitter
John Spicer

Created on 2002-04-16.00:00:00 last changed 157 months ago

Messages

Date: 2003-10-15.00:00:00

[Voted into WP at October 2003 meeting.]

Date: 2003-04-15.00:00:00

Proposed resolution (April 2003):

Add to the end of 13.10.3.4 [temp.deduct.conv] (as a new paragraph following paragraph 3):

When the deduction process requires a qualification conversion for a pointer or pointer to member type as described above, the following process is used to determine the deduced template argument values:

If A is a type cv1,0 pointer to ... cv 1,n-1 pointer to cv1,n T1

and P is a type cv2,0 pointer to ... cv2,n-1 pointer to cv2,n T2

The cv-unqualified T1 and T2 are used as the types of A and P respectively for type deduction.

[Example:

struct A {
	template <class T> operator T***();
};

A a;
const int * const * const * p1 = a;  // T is deduced as int, not const int
-- end example]

Date: 2002-10-15.00:00:00

Notes from October 2002 meeting:

There was consensus on having the deduced type be "int" in the above.

Date: 2004-09-10.00:00:00

We ran into an issue concerning qualification conversions when doing template argument deduction for conversion functions.

The question is: What is the type of T in the conversion functions called by this example? Is T "int" or "const int"?

If T is "int", the conversion function in class A works and the one in class B fails (because the return expression cannot be converted to the return type of the function). If T is "const int", A fails and B works.

Because the qualification conversion is performed on the result of the conversion function, I see no benefit in deducing T as const int.

In addition, I think the code in class A is more likely to occur than the code in class B. If the author of the class was planning on returning a pointer to a const entity, I would expect the function to have been written with a const in the return type.

Consequently, I believe the correct result should be that T is int.

struct A {
	template <class T> operator T***() {
		int*** p = 0;
		return p;
	}
};

struct B {
	template <class T> operator T***() {
		const int*** p = 0;
		return p;
	}
};

int main()
{
	A a;
	const int * const * const * p1 = a;
	B b;
	const int * const * const * p2 = b;
}

We have just implemented this feature, and pending clarification by the committee, we deduce T as int. It appears that g++ and the Sun compiler deduce T as const int.

One way or the other, I think the standard should be clarified to specify how cases like this should be handled.

History
Date User Action Args
2008-10-05 00:00:00adminsetstatus: wp -> cd1
2004-04-09 00:00:00adminsetmessages: + msg1029
2003-11-15 00:00:00adminsetstatus: ready -> wp
2003-04-25 00:00:00adminsetstatus: review -> ready
2002-11-08 00:00:00adminsetmessages: + msg746
2002-11-08 00:00:00adminsetmessages: + msg745
2002-11-08 00:00:00adminsetstatus: open -> review
2002-04-16 00:00:00admincreate