How many implicit conversions can C++ do to convert one user-defined type to another when initializing class types?

Viewed 89
#include <iostream>

struct Gadget
{
  Gadget() { puts("Gadget default"); }
  Gadget(char const *a) { puts("Gadget-const char* constructor"); }
  Gadget(Gadget const &other) { puts("Gadget copy"); }
  ~Gadget() { puts("\nGadget destruction"); }
};

struct Work
{
  Work() { puts("default"); }
  Work(const Gadget &a) { puts("Work-Gadget constructor"); }
  // Work(char const *a) { puts("Work-const char* constructor"); }
  Work(Work const &other) { puts("copy"); }
  ~Work() { puts("\nWork destruction"); }
};

int main()
{
  using namespace std;
  Work w = "std";  // error here;
}

But

Work w("std"); // works fine
Work w = Gadget("std"); // works fine
Work w = Work("std"); // works fine

Is there any limit for implicit conversion that c++ can do? If so then at what context does implicit conversion happen?

1 Answers

Only one user-defined conversion is allowed in implicit conversion sequence. (BTW standard conversions don't have such limits.) Work w = "std"; performs copy initialization, it requires two user-defined conversions, one from char const * to Gadget, and one from Gadget to Work.

Work w("std"); performs direct initialization, only one user-defined conversion (from char const * to Gadget) is required, then the converted Gadget is passed to the constructor of Work directly to construct w.

the implicit conversion in copy-initialization must produce T directly from the initializer, while, e.g. direct-initialization expects an implicit conversion from the initializer to an argument of T's constructor.

In Work w = Work("std");, a temporary Work is constructed explicitly as Work("std") (which works as above explained), then w is copy-initialized from the temporary Work.

In Work w = Gadget("std");, a temporary Gadget is constructed explicitly as Gadget("std"), then w is copy-initialized from the temporary Gadget; in which only one user-defined conversion (from Gadget to Work) is required.

Related