Copy initialization with conversion operator

Sarvesh :

There is code in copy_initialization

struct A 
{
  operator int() { return 12;}
};

struct B 
{
  B(int) {}
};
int main()
{
 ....
    A a;
    B b0 = 12;
//    B b1 = a; //< error: conversion from 'A' to non-scalar type 'B' requested
    B b2{a};        // < identical, calling A::operator int(), then B::B(int)
    B b3 = {a};     // <
    auto b4 = B{a}; // <
}

Now question is

  • How does Direct initialization work in case of b2? Can Direct initialization call conversion operator?
  • Why Copy initialization fails for b1? Implicitly A should be converted to int and B's constructor can be called.
  • b3 is also Copy initialization but it works. Why so?
Nicol Bolas :

This is very simple: implicit convertibility (for user-defined types) is not a transitive property in C++. That is, while A is convertible to int, and int is convertible to B, this does not by itself mean that A is convertible to B. There is no valid implicit conversion sequence from A to B, so A is not convertible to B.

Copy initialization requires implicit convertibility between the type of the initialization expression and the type being initialized. Since A is not convertible to B, b1 doesn't compile.

Anytime you see {} as part of an initialization like this, then this means that the object it applies to is going to undergo some form of list initialization, which is a different process from the other forms of initialization.

b2 does not perform "direct initialization". It performs direct list initialization, which is one of two forms of list initialization. The rules of list initialization, in this case, eventually boil down to using overload resolution on the set of constructors for B. There is a constructor of B which can be called with an A, since that call can happen via implicit conversion of the A to an int.

b3 is not "copy initialization"; it is copy list initialization, which has absolutely nothing to do with "copy initialization". Copy-list-initialization is identical to direct-list-initialization with exactly two exceptions, neither of which apply to this case. So it does the same thing as b2.

Guess you like

Origin http://10.200.1.11:23101/article/api/json?id=376200&siteId=1