Assigning a double to a struct

c++

Solution

During the compilation this:

ms = a;

attempts to resolve an assignment of one or more of the following immediate forms

my_struct& operator ()(double)
my_struct& operator ()(double&)
my_struct& operator ()(const double&)

and a litany of other potential conversion from `double`. And none is found. In fact, only the following is discovered:

my_struct& operator=(const my_struct &ms)

which indicates the compiler does allow assignment via a const-reference of another `my_struct`. At that time a conversion constructor is sought, starting with the most immediate conversion (explicit to the type `double`:

my_struct(double)
my_struct(double&)
my_struct(const double&)

It is important to note such a constructor cannot mandate explicit use. We're implicitly constructing a temporary, and as such explicit mandate is off the reservation.

Anyway, again, none is found. Before giving up the compiler attempts to locate a constructor of any form that can convert from `double` to whatever the fundamental construction requires and said constructor supports implicit construction. In effect, something of the form

my_struct(<<something that can be converted from a double>>)

And again, the constructor cannot be `explicit`. As it turns out, this search does find this:

my_struct(char)

because `double` can be converted to `char` (albeit poorly and likely not what you want). The entire chain is a little (ok, a lot) more complicated than that, but that is the crux of it.

You can avoid this implicit construction by ensuring that constructor is only `explicit` in usage, but that is a double-edge sword, so care is required. Use of `explicit` can be somewhat harsh. Doing this:

explicit my_struct(char)

will squelch the unintended implicit construction when converting `double` to `char`. But I warn you; it will also squelch the ability to do this:

char x = 'a';
my_struct ms;
ms = x;

because now `my_struct` cannot be implicitly constructed at all from `char`, by conversion or otherwise. There are multiple ways around this, including defining a specific assignment operator for the type (takes a `double`) or a specific conversion constructor (takes a `double`). How you approach that I leave to you.

Problem

I stumbled upon something the other day in the code of a colleague and I want to understand how/why this works. He uses a struct like this ``` struct my_struct { my_struct(){ /* default constructor*/}; my_struct(char c){ /*some special constructor*/}; // other stuff my_struct& operator=(const my_struct &ms){ /* assignment */}; }; ``` Originally through a typo he figured out that the following works ``` my_struct ms; double a; ms = a; ``` I have worked out that this is equal (in the sense of gives the same final struct ms) to the following ``` my_struct ms; double a; my_struct ms2((char) a); ms=ms2; ``` But I don't know why. Personally, I think this should not work, because there is no assign operator for double and my_struct and additionally because there is no constructor for my_struct using a double. I tried to google this, but did not find anything relevant. @ user657267: i wanted to keep it as short as possible, you could add a line a=5; or whatever the same would apply.

Original source