This is an unofficial snapshot of the ISO/IEC JTC1 SC22 WG21 Core Issues List revision 115d. See http://www.open-std.org/jtc1/sc22/wg21/ for the official list.
2024-10-26
[Voted into WP at October 2003 meeting.]
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.
Notes from October 2002 meeting:
There was consensus on having the deduced type be "int" in the above.
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]