Boost variant ambiguous construction [duplicate]

2019-06-16 18:42发布

问题:

This question already has an answer here:

  • boost::variant - why is “const char*” converted to “bool”? 2 answers

The Boost Variant documentation says the following of the constructor that accepts arbitrary type:

template<typename T> variant(T & operand);
  • Requires: T must be unambiguously convertible to one of the bounded types (i.e., T1, T2, etc.).

The same is true of the constructors accepting const T& and T&&. So I expect that the following code won't compile:

boost::variant<std::string, bool> v = "text";

But the code compile, and v becomes a bool, which is something I definitely did not want. Of course the solution is to wrap the string literal in a std::string constructor. My question is:

  1. Why does this code compile?
  2. How does it choose the type (as const char* is convertible to both std::string and bool)?

回答1:

Generally, user-defined conversions lose overload resolution process to standard conversions.

There is a built-in conversion from const char pointers to bool which is preferred over the non-built-in conversion from const char * to std::string (e.g. see Implicit conversions).

std::string, while part of the standard library, is not a built-in type so its conversion constructors are considered only after conversions to built-in types.

Some references:

  • Why does the compiler choose bool over string for implicit typecast of L""?
  • Why is my overloaded C++ constructor not called?