Title
Overload resolution for reference binding of similar types
Status
dr
Section
12.2.4.2.5 [over.ics.ref]
Submitter
Brian Bi

Created on 2023-06-14.00:00:00 last changed 3 weeks ago

Messages

Date: 2023-12-02.15:54:05

Proposed resolution (approved by CWG 2023-11-10):

  1. Change in 12.2.4.2.5 [over.ics.ref] paragraph 1 as follows:

    When a parameter of reference type "reference to cv T" binds directly (9.4.4 [dcl.init.ref]) to an argument expression, the implicit conversion sequence is the identity conversion, unless:
    • If the argument expression has a type that is a derived class of the parameter type, in which case the implicit conversion sequence is a derived-to-base conversion (12.2.4.2 [over.best.ics]).
    • Otherwise, if T is a function type, or if the type of the argument is possibly cv-qualified T, or if T is an array type of unknown bound with element type U and the argument has an array type of known bound whose element type is possibly cv-qualified U, the implicit conversion sequence is the identity conversion. [ Note: When T is a function type, the type of the argument may differ only by the presence of noexcept. -- end note]
    • Otherwise, the implicit conversion sequence is a qualification conversion.

    [Example 1: ... —end example]

    If the parameter binds directly to the result of applying a conversion function to the argument expression, the implicit conversion sequence is a user-defined conversion sequence (12.2.4.2.3 [over.ics.user]) whose second standard conversion sequence is either an identity conversion or, if the conversion function returns an entity of a type that is a derived class of the parameter type, a derived-to-base conversion determined by the above rules.
  2. Change in 12.2.4.3 [over.ics.rank] bullet 3.2.5 as follows:

    • S1 and S2 differ only in their qualification conversion (7.3.6 [conv.qual]) and yield similar types T1 and T2, respectively (where a standard conversion sequence that is a reference binding is considered to yield the cv-unqualified referenced type), where T1 can be converted to T2 by a qualification conversion and T2 are not the same type, and const T2 is reference-compatible with T1 (9.4.4 [dcl.init.ref]). [Example 5:
        int f(const volatile int *);
        int f(const int *);
        int i;
        int j = f(&i);  // calls f(const int*)
        int g(const int*);
        int g(const volatile int* const&);
        int* p;
        int k = g(p);          // calls g(const int*)
      
      -- end example] or, if not that,
  3. Change in 12.2.4.3 [over.ics.rank] bullet 3.2.6 as follows:

    • S1 and S2 include reference bindings bind "reference to T1" and "reference to T2", respectively (9.4.4 [dcl.init.ref]), and the types to which the references refer are the same type except for top-level cv-qualifiers, and the type to which the reference initialized by S2 refers is more cv-qualified than the type to which the reference initialized by S1 refers where T1 and T2 are not the same type, and T2 is reference-compatible with T1. [Example 6: ...
         int h1(int (&)[]);
         int h1(int (&)[1]);
         int h2(void (&)());
         int h2(void (&)() noexcept);
         void g2() {
           int a[1];
           h1(a);            // calls h1(int (&)[1])
           extern void f2() noexcept;
           h2(f2);            // calls h2(void (&)() noexcept)
         }
      
      -- end example ]
Date: 2024-03-15.00:00:00

[Accepted as a DR at the March, 2024 meeting.]

Consider:

  int foo(int*& r);       // #1
  int foo(const int* const& r); // #2

  int *p;
  int x = foo(p);

Both #1 and #2 perform direct reference binding; no qualification conversions are involved. Despite the lack of a rule, implementations prefer #1 over #2.

History
Date User Action Args
2024-04-05 21:43:46adminsetstatus: ready -> dr
2024-03-20 14:10:31adminsetstatus: tentatively ready -> ready
2023-12-02 15:54:05adminsetstatus: review -> tentatively ready
2023-10-20 21:07:14adminsetstatus: open -> review
2023-10-04 06:48:59adminsetmessages: + msg7448
2023-06-14 00:00:00admincreate