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 does the second expression fail to compile? I expected that it would call the same converting constructor as same as the first expression.
Implicit Type Conversion is also known as 'automatic type conversion'. It is done by the compiler on its own, without any external trigger from the user. It generally takes place when in an expression more than one data type is present.
Copy Constructor in C++ In simple terms, a constructor which creates an object by initializing it with an object of the same class, which has been created previously is known as a copy constructor.
Direct Initialization or Assignment Operator (Syntax) This assigns the value of one object to another object both of which are already exists. Copy initialization is used when a new object is created with some existing object. This is used when we want to assign existing object to new object.
Implicit conversions: No special syntax is required because the conversion always succeeds and no data will be lost. Examples include conversions from smaller to larger integral types, and conversions from derived classes to base classes.
From [dcl.init]:
Otherwise (i.e., for the remaining copy-initialization cases), user-defined conversion sequences that can convert from the source type to the destination type or (when a conversion function is used) to a derived class thereof are enumerated as described in 13.3.1.4, and the best one is chosen through overload resolution (13.3).
We can invoke a user-defined conversion that is from the source type directly to the target type. That is, if we had Bar(float )
, we would consider that constructor. However, in this case, our candidate is simply Bar(Foo )
, which does not take a float
.
You are allowed zero or one user-defined conversion. In the direct-initialization case, we simply call Bar(Foo )
which invokes one user-defined conversion (float --> Foo
). In the copy-initialization case, we are looking for a conversion sequence from float
(the source type) all the way to Bar
(the destination type), which would involve two user-defined conversions (float --> Foo
, Foo --> Bar
), hence the error.
The second type of initialization is called copy-initialization and uses copy constructor. Therefore, this type of initialization expects the right side is convertible to Bar.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With