Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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 does the second expression fail to compile? I expected that it would call the same converting constructor as same as the first expression.

like image 927
Addict Avatar asked Aug 17 '15 14:08

Addict


People also ask

What is implicit conversion in C?

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.

What is the other name for copy initialization?

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.

What is assignment and copy initialization?

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.

What is implicit conversion give an example?

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.


2 Answers

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.

like image 101
Barry Avatar answered Oct 09 '22 16:10

Barry


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.

like image 31
Eugene Avatar answered Oct 09 '22 15:10

Eugene