boost :: get boost :: variant没有给出正确的输出

时间:2013-07-15 20:08:18

标签: c++ boost-variant

我有以下功能

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;

为什么?

2 个答案:

答案 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胜过字符串。