Created on 2009-10-01.00:00:00 last changed 178 months ago
[Voted into WP at March, 2010 meeting.]
Proposed resolution (February, 2010):
Change 13.10.3.4 [temp.deduct.conv] paragraphs 1-3 as follows, inserting a new paragraph between the current paragraphs 1 and 2:
Template argument deduction is done by comparing the return type of the conversion function template (call it P; see 9.4 [dcl.init], 12.2.2.6 [over.match.conv], and 12.2.2.7 [over.match.ref] for the determination of that type) with the type that is required as the result of the conversion (call it A) as described in 13.10.3.6 [temp.deduct.type].
If P is a reference type, the type referred to by P is used in place of P for type deduction and for any further references to or transformations of P in the remainder of this section.
If A is not a reference type:
If P is an array type, the pointer type produced by the array-to-pointer standard conversion (7.3.3 [conv.array]) is used in place of P for type deduction; otherwise,
If P is a function type, the pointer type produced by the function-to-pointer standard conversion (7.3.4 [conv.func]) is used in place of P for type deduction; otherwise,
If P is a cv-qualified type, the top level cv-qualifiers of P's type are ignored for type deduction.
If A is a cv-qualified type, the top level cv-qualifiers of A's type are ignored for type deduction. If A is a reference type, the type referred to by A is used for type deduction.
If P is a reference type, the type referred to by P is used for type deduction.
(This resolution also resolves issues 493 and 913.)
[Drafting note: This change intentionally reverses the resolution of issue 322 (and applies it in a different form).]
Consider this program:
struct F { template<class T> operator const T&() { static T t; return t; } }; int main() { F f; int i = f; // ill-formed }
It's ill-formed, because according to 13.10.3.4 [temp.deduct.conv], we try to match const T with int.
(The reference got removed from P because of paragraph 3, but the const isn't removed, because bullet 2.3 comes before paragraph 3 and thus isn't applied any more.)
Changing the declaration of the conversion operator to
operator T&() { ... }
makes the program compile, which is counter-intuitive to me: I'm in an rvalue (read-only) context, and I can use a conversion to T&, but I can't use a conversion to const T&?
History | |||
---|---|---|---|
Date | User | Action | Args |
2010-03-29 00:00:00 | admin | set | messages: + msg2745 |
2010-03-29 00:00:00 | admin | set | status: tentatively ready -> cd2 |
2010-02-16 00:00:00 | admin | set | messages: + msg2516 |
2010-02-16 00:00:00 | admin | set | status: drafting -> tentatively ready |
2009-10-01 00:00:00 | admin | create |