Copy-initialization with implicit conversion in C ++

class Foo { public: Foo(float b) {} }; class Bar { public: Bar(Foo foo) {} }; int main(int argc, char *argv[]) { Bar b1(3.0f); // accept, one implicit convertion happens there. Bar b2 = 3.0f; // error: no viable conversion from 'float' to 'Bar' return 0; } 

Why can't the second expression compile? I expected him to call the same transform constructor as the first expression.

+6
source share
2 answers

From [dcl.init]:

Otherwise (that is, for the remaining cases of copy initialization), user-defined conversion sequences that can convert from a source type to a destination type or (when the conversion function) to its derived class are listed as described in 13.3.1.4, and the best of them are selected using overload permissions (13.3).

We can invoke a custom conversion that relates to the source type directly to the target type. That is, if we had Bar(float ) , we would consider this constructor. However, in this case, our candidate is simply Bar(Foo ) , which does not accept float .

You are allowed zero or one custom conversion. In the case of direct initialization, we simply call Bar(Foo ) , which calls one user-defined conversion ( float --> Foo ). In case of initialization of the copy, we look for a sequence of transformations from float (source type) up to Bar (destination type), which includes two user transformations ( float --> Foo , Foo --> Bar ), therefore, an error.

+7
source

The second type of initialization is called copy-initialization and uses the copy constructor. Therefore, this type of initialization expects the right side to be converted to Bar.

+3
source

All Articles