1

我有以下功能

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

为什么 ?

4

2 回答 2

2

原因是字符串文字 ( char*) 转换为bool比 to 更好,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

于 2013-07-15T20:27:49.000 回答
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 胜过字符串。

于 2013-07-15T20:27:55.617 回答