Reputation: 2179
I have the following function
template <typename T, typename U>
const T* visitor_fct(U& operand)
{
return (boost::get<T>(&operand));
}
When I do
boost::variant<int, std::string> str = "string";
std::cout << visitor_fct<std::string>(str) << std::endl;
I get the correct output
But when I change the declaration of str to :
boost::variant<int, std::string, bool> str = "toto";
I am always getting a nullptr
;
Why ?
Upvotes: 1
Views: 200
Reputation: 96301
The reason is that a string literal (char*
)converts to bool
better than to std::string
so your string literal doesn't initialize the string
component of the variant, but rather than bool
component (to true).
See the following which outputs bool 1
:
#include <iostream>
void foo(bool b)
{
std::cout << "bool " << b << std::endl;
}
void foo(std::string s)
{
std::cout << "string " << s << std::endl;
}
int main()
{
foo("Bar");
}
Initializing with std::string("toto")
will solve your problem.
4.12/1 shows us the conversion in question:
A prvalue of arithmetic, unscoped enumeration, pointer, or pointer to member type can be converted to a
prvalue of type bool. A zero value, null pointer value, or null member pointer value is converted to false;
any other value is converted to true. A prvalue of type std::nullptr_t can be converted to a prvalue of
type bool; the resulting value is false.
[As noted also in the other answer] This implicit conversion takes precedence over the converting constructor of std::string
and so is selected, causing the type used in the variant to be bool
.
Upvotes: 2
Reputation: 15916
What seems to be happening here is because there's a bool present in the boost::variant, the const char* you're passing is no longer used for the string but rather is converted to bool.
if you change this line:
boost::variant<int, std::string, bool> str = "toto";
to this:
boost::variant<int, std::string, bool> str = std::string("toto");
it will work.
Here's why the bool gets chosen over the string: implicit conversions happen between any types of pointer and bool, and conversions between built-in types are always preferred to user-defined conversions. And since std::string is a user defined type (standard mind you but still user defined) the bool wins over the string.
Upvotes: 2