Strange constructor behavior

  • A+
Category:Languages

I am using VS2013 and this is what I'm trying to figure out:

#include <iostream> #include <vector> using namespace std;  class A { public:     int x = 1;     bool y = true;      A(int _x, bool _y) : x(_x), y(_y)     {         cout << "Constructor #1" << endl;     }      A(std::initializer_list<int> init_list)     {         cout << "Constructor #2" << endl;     } };   int main(int argc, char** argv) {     A Aobj1(10, false);     A Aobj2(20, "false");     A Aobj3{ 30, false };     A Aobj4{ 40, "false" };      return 0; } 

The output is:

Constructor #1 Constructor #1 Constructor #2 Constructor #1 
  • The first call to constructor #1 is fine

  • Now the second construction of Aobj2(int, string) calling constructor #1 is strange. How is the compiler calling the (int, bool) constructor with a string argument? The "false" bool is not even converted to an int.

  • Aobj3 is also OK. Although the initializer_list is of type int, the compiler calls this because of brace-initialization and converts the bool to an int.

  • This one again baffles me. I would have expected this to be an error because a string cannot be converted to an int (as it was with the bool), and also expected the compiler to be calling the initializer_list constructor because it is a braced initialization. But the compiler chooses the (int, bool) constructor.

Could someone please she some background on to the logic of the compiler? Thank you.

 


"false" is a const char[6] which decays to const char* and pointers are implicitly convertible to bool. That's why the compiler can call your constructor taking a int and a bool, since the compiler is allowed to perform one implicit conversion to make a function argument match.

Comment

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen: