Title
Deduction for const T& conversion operators
Status
cd2
Section
13.10.3.4 [temp.deduct.conv]
Submitter
Jens Maurer

Created on 2009-10-01.00:00:00 last changed 171 months ago

Messages

Date: 2010-03-15.00:00:00

[Voted into WP at March, 2010 meeting.]

Date: 2010-02-15.00:00:00

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).]

Date: 2022-02-18.07:47:23

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:00adminsetmessages: + msg2745
2010-03-29 00:00:00adminsetstatus: tentatively ready -> cd2
2010-02-16 00:00:00adminsetmessages: + msg2516
2010-02-16 00:00:00adminsetstatus: drafting -> tentatively ready
2009-10-01 00:00:00admincreate