1

Please, look at this code:

#include <iostream>
class A {
  public:
    int my;
    A(int a=0) : my(a) { }
};

int main() {
  A x = 7; // 1
  A y = 6.7; // 2
  std::cout << x.my << " " << y.my << "\n";
}

It actually compiles although there is no A(double a); constructor. When exactly compiler is allowed to convert one argument type to another to call corresponding constructor?

Ryan Haining
  • 35,360
  • 15
  • 114
  • 174
hungry91
  • 133
  • 8
  • `When exactly compiler is allowed to convert` Everytime [when an implicit conversion is possible and no better method]. – deviantfan Jun 20 '15 at 19:00
  • [This reference](http://en.cppreference.com/w/cpp/language/implicit_cast) lists the standard conversions. Of particular interest here are floating-integral conversions. – chris Jun 20 '15 at 19:05
  • Also, look up the difference between construction, `A x(7)` and assignment, `x = 7;` – Thomas Matthews Jun 20 '15 at 19:10

1 Answers1

3

cppreference has a list of standard conversions. Of interest to you is the Floating - integral conversions section which can also be found in N4140 4.9/1

A prvalue of floating-point type can be converted to prvalue of any integer type. The fractional part is truncated, that is, the fractional part is discarded.

Finding A(int) to be callable with a standard conversion, the compiler inserts the necessary step to make the code work. It's the same rule that allows int x = 1.1 to compile

If this behavior is undesirable you can forbid it with an =delete

class A {
  public:
    //...
    A(int a);
    A(double) =delete;
};    
Ryan Haining
  • 35,360
  • 15
  • 114
  • 174