我在boost::variant
上遇到麻烦(使用Boost 1.67.0)。
当我的模板参数列表同时包含bool
和std::string
时,应视为字符串的任何变体对象似乎都隐式绑定到bool上。例如:
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";
}
输出:
[1 0 1]
如果我只将第一个模板参数从bool
更改为int
,则一切正常:
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";
}
正确输出:
[1 0 Hello_World]
有什么想法吗?
答案 0 :(得分:3)
boost::variant
对于每种声明的类型都有一个构造函数重载。在您的第一个示例中,bool
将有一个重载,std::string
将有一个重载。现在,您正在使用char[n]
调用构造函数,该构造函数可以隐式转换为它们两个。因此,没有完美的匹配,只有两个候选人。但是编译器不会告诉您调用是模棱两可的,而是会选择bool
重载作为更好的匹配。
为什么? in this question已经很好地回答了。
在带有int
和std::string
的第二个示例中,您将bool
和char[n]
传递给构造函数。 bool
可隐式转换为int
,但不能转换为std::string
。 char[n]
可隐式转换为std::string
,但不能转换为int
。因此,称为构造函数是因为每个构造函数只有一个候选。