我有以下功能
template <typename T, typename U>
const T* visitor_fct(U& operand)
{
return (boost::get<T>(&operand));
}
当我这样做时
boost::variant<int, std::string> str = "string";
std::cout << visitor_fct<std::string>(str) << std::endl;
我得到正确的输出
但是当我将str的声明改为:
时 boost::variant<int, std::string, bool> str = "toto";
我总是得到nullptr
;
为什么?
答案 0 :(得分:2)
原因是字符串文字(char*
)转换为bool
优于std::string
,因此您的字符串文字不会初始化变体的string
组件,而不是bool
组件(到真)。
请参阅以下输出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");
}
使用std::string("toto")
初始化可以解决您的问题。
4.12 / 1向我们展示了有问题的转换:
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.
[正如另一个答案中所述]这种隐式转换优先于std::string
的转换构造函数,因此被选中,导致变体中使用的类型为bool
。
答案 1 :(得分:2)
这里似乎发生的事情是因为boost :: variant中存在bool,你传递的const char *不再用于字符串,而是转换为bool。
如果你改变这一行:
boost::variant<int, std::string, bool> str = "toto";
到此:
boost::variant<int, std::string, bool> str = std::string("toto");
它会起作用。
这就是为什么在字符串上选择bool的原因:隐式转换发生在任何类型的指针和bool之间,内置类型之间的转换总是优先于用户定义的转换。由于std :: string是用户定义的类型(标准介意你,但仍然是用户定义的)bool胜过字符串。