What I would like to ask about is a different issue, which is implicit conversions.
One thing that was slightly annoying to me about boost::variant was that things like this would compile:
```
boost::variant<std::string, int> v;
v = true
```
and types like `boost::variant<int, float>` could often lead to ambiguous overload resolution when making assignments to them.
In one project, I wanted to use `boost::variant` to represent a value from an interface with a scripting language, which naturally would have been `boost::variant<bool, int, float, std::string, ...>`. But I found it more complicated than I would like to figure out exactly what the variant was doing when I made assignments to it. Probably because I'm still a novice and I generally understand overload resolution from experience rather than from a close reading of the standard.
What I ended up doing in that project instead was, I made a different variant type in which overload resolution is not used, and instead it uses an iterative strategy. I made a type trait that eliminates undesirable integral conversions, and prevents conversions between integral, floating point, pointer type, character type, boolean, and wchar_t, and prevents narrowing conversions. (I won't describe my trait in full detail.)
There are a few drawbacks to a variant like this that I can see.
- With the overload-resolution-based implementation when no match is found, the compiler will give you list of reasons in each case why the overload was rejected. When you do iteration via TMP, when you get to the end of the list the only real error you can give is "no match found". I suppose you could try to use some really fancy TMP that will accumulate a list of errors and put that info in the static assert, but I didn't attempt that.
- Overload resolution is a core language feature and everyone already knows how it works more or less. So even if it doesn't always do what they want, people will be more comfortable with a variant based on overload resolution and it will feel more familiar to them.
I guess what I'd like to ask is, since the designers of std::variant thought that this issue was much less important than the "never empty" guarantee, can anyone give some insight into how they view this issue? I used my no-overload resolution version in another project for a while now and I didn't experience any major usability issues. But maybe there are more subtle issues I didn't think about, or advantages of the overload-resolution strategy that I didn't know of.
Would be very interested to hear peoples' opinions.
Best Regards,
Chris Beck