Overload resolution when the argument is a list of initializers and the parameter is a reference

struct A { A(int);};
struct B { explicit B(A); B(const B&);};
B b({0}); 

I asked a question Permission overload got a different result between gcc and clang , and @Johannes Schaub-litb explained the rules that are active. But I still have some questions about 13.3.3.1.4 Link Binding .

N4527 13.3.3.1.5 [over.ics.list] p1 and p8

1 If the argument - this is a list of initializers (8.5.4), this is not an expression , and special rules are used for conversion to the type of parameter.

8 Otherwise, if the parameter is a reference, see 13.3.3.1.4.

13.3.3.1.4 [over.ics.ref] p1 and p2

1 (8.5.3) , - , , , (13.3.3.1). [...]

-, (13.3.3.1.2), , , , , .

2 , , 13.3.3.1. . .

1: "" ? . 13.3.3.1.5 [over.ics.list] p1

1.3.2 [defns.argument]

< function call expression > , , (5.2.2)



8.5 [dcl.init] p17

17 . - , , - . (, ), .

(17.1). ( ) -init-list, (8.5.4).

     

(17.2) - , . 8.5.3.

8.5.3 [dcl.init.ref] p5

"cv1 T1" "cv2 T2" :

[...]

     

(5.2.2.2) - "cv1 T1" (8.5)   . .

     

[...]

, (.. ), .

2. " " , ? , " ", ?

. " " - 8.5.3, 8.5 p17.1, "initializer - " - 8.5.4, 8.5 p17.2

//case 5.2.1.2
struct X{};

struct Y{Y(X);};
const Y& y1 = X();     // bind directly
const Y& y2 = {X()};   // bind directly or not?

struct Z{operator X();};
const X& x1 = Z();     // bind directly
const X& x2 = {Z()};   // bind directly or not?

//case 5.2.2.1
struct A{operator int();};
const int& a1 = A();   // bind directly
const int& a2 = {A()}; // bind directly or not?

struct B{B(int);};
const B& b1 = 1;       // bind directly
const B& b2 = {1};     // bind directly or not?

//csse 5.2.2.2
int i3 = 2;
double&& rrd3 = i3;    // not bind directly

struct A { A(int);};
struct B { explicit B(A); B(const B&);};
B b({0}); // when overload resolution choose B(const B&) as a candidate,
          // {0} -> constB& bind directly or not? 


3 ( ):

, , 13.3.3.1.5 [over.ics.list] p8 13.3.3.1.4 [over.ics.ref], . , . , " " "" " ".

, , , ?

. . , .

struct A { A(int);};
struct B { explicit B(A); B(const B&);};
B b1(0); //when overload resolution choose B(const B&) as a candidate,
         //0 -> const B& binds directly
         //13.3.3.1.4 [over.ics.ref] p1 "If the parameter binds directly..."
A a;
B b2(a)  //when overload resolution choose B(const B&) as a candidate,
         //a -> const B& binds directly
         //13.3.3.1.4 [over.ics.ref] p1 "If the parameter binds directly..."
B b3({0})//when overload resolution choose B(const B&) as a candidate,
         //{0} -> const B& binds directly or not?
         //if it is not bound directly, 13.3.3.1.4 [over.ics.ref] p2
B b3({a})//when overload resolution choose B(const B&) as a candidate,
         //{a} -> const B& binds directly or not?
         //if it is not bound directly, 13.3.3.1.4 [over.ics.ref] p2
+4
1

, http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1536 ( , ).

, over.ics.ref , ( decl.init.list) . , over.ics.list , over.ics.ref over.ics.list , , over.ics.ref ( decl.init.list, ). , { } ClassType& , , rvalue refefence , .

+2

Source: https://habr.com/ru/post/1611236/


All Articles