问题
I'm having trouble with boost::variant
(using boost 1.67.0).
When my template parameter list includes both bool
and std::string
, any variant objects which should be treated as string, seem to be implicitly bound to bool instead. For example:
using Varval = boost::variant<bool, std::string>;
void main()
{
std::vector<Varval> vect{ true, false, "Hello_World" };
std::cout << "[ ";
for (const auto &v : vect)
std::cout << v << " ";
std::cout << "]\n";
}
Outputs:
[ 1 0 1 ]
whereas if I change nothing but the first template argument, from bool
to int
, it works fine:
using Varval = boost::variant<int, std::string>;
void main()
{
std::vector<Varval> vect{ true, false, "Hello_World" };
std::cout << "[ ";
for (const auto &v : vect)
std::cout << v << " ";
std::cout << "]\n";
}
Properly outputs:
[ 1 0 Hello_World ]
Any ideas?
回答1:
boost::variant
has one constructor overload for each stated type. In your first example there will be one overload for bool
and one for std::string
. You are now calling the constructor with a char[n]
which can be imlicitly converted to both of them. So there is no perfect match but two candidates. But instead of telling you that the call is ambiguous, the compiler will choose the bool
overload as the better match.
Why? That is already perfectly answered in this question.
In your second example with int
and std::string
you are passing bool
s and char[n]
to the constructors. bool
is implicitly convertable to int
but not to std::string
. char[n]
is implicitly convertable to std::string
but not to int
. So the according constructors are called as there is only one candidate for each.
来源:https://stackoverflow.com/questions/50957837/boostvariant-with-bool-and-string