C++ boost::variant将静态应用于某些类型

C++ boost::variant将静态应用于某些类型,c++,boost,boost-variant,static-visitor,C++,Boost,Boost Variant,Static Visitor,我有以下变体: typedef boost::variant<int, float, bool> TypeVariant; 但是,这给了我一条错误消息: “TypeVariant ConvertToBool::operator()(float)const”:无法将参数1从“T”转换为“float” 允许访问者只应用于某些类型的正确方法是什么?只包括缺少的重载: template <typename T> TypeVariant operator()(T const&am

我有以下变体:

typedef boost::variant<int, float, bool> TypeVariant;
但是,这给了我一条错误消息:

“TypeVariant ConvertToBool::operator()(float)const”:无法将参数1从“T”转换为“float”


允许访问者只应用于某些类型的正确方法是什么?

只包括缺少的重载:

template <typename T> TypeVariant operator()(T const& a) const {
    return static_cast<bool>(a);
}

#include <boost/variant.hpp>
#include <iostream>

using TypeVariant = boost::variant<int, float, bool>;

struct ConvertToBool {
    using result_type = TypeVariant;
    TypeVariant operator()(TypeVariant const& v) const {
        return boost::apply_visitor(*this, v);
    }

    TypeVariant operator()(int   a) const { return a != 0; }
    TypeVariant operator()(float a) const { return a != 0; }
    TypeVariant operator()(bool  a) const { return a; }
} static constexpr to_bool{};

int main() {
    using V = TypeVariant;
    
    for (V v : {V{}, {42}, {3.14f}, {true}}) {
        std::cout << v << " -> " << std::boolalpha << to_bool(v) << "\n";
    }
}
#include <boost/variant.hpp>
#include <iostream>

using TypeVariant = boost::variant<int, float, bool>;

struct ConvertToBool {
    using result_type = TypeVariant;
    TypeVariant operator()(TypeVariant const& v) const {
        return boost::apply_visitor(*this, v);
    }

    template <typename T> TypeVariant operator()(T const& a) const {
        return static_cast<bool>(a);
    }
} static constexpr to_bool{};

int main() {
    using V = TypeVariant;

    for (V v : { V{}, { 42 }, { 3.14f }, { true } }) {
        std::cout << v << " -> " << std::boolalpha << to_bool(v) << "\n";
    }
}

为什么不把布尔转换成布尔呢?另外,考虑返回BooL而不是一个变体。@ Yakk AddNavaRuMunt,你把BoL转换成BoL是什么意思?非常感谢你的详细回答。是的,这个布尔转换的例子只是我真实问题的一个简化问题,这些例子完美地回答了这个问题。关于第一个示例,我还有一个问题:当我将
std::string
添加到变量中,并且没有为其指定运算符重载时,当将std::string传递到
到\u bool
时,它返回一个true。为什么会这样?我希望它崩溃,因为没有指定重载。我希望它不会编译,不会崩溃。但是很明显,是的,有一个漏洞导致了它:看到了吗。启用asan/ubsan:它只是重复地点击
VariantType
重载。我以前没有意识到这是一个潜在的错误源(在可调用类型中执行
apply\u visitor
)。我通常这样设置:-单独的(私有的和潜在的静态的)
调用
实现[现在它不编译]。此外,这个习惯用法使得在递归变量上实现访问者变得优雅,因为例如
return call(x)+call(y)
看起来比
return operator()(x)+operator()(y)
更好,甚至比
return(*this)(x)+(*this)(y)更糟糕
#include <boost/variant.hpp>
#include <iostream>

using TypeVariant = boost::variant<int, float, bool>;

struct ConvertToBool {
    using result_type = TypeVariant;
    TypeVariant operator()(TypeVariant const& v) const {
        return boost::apply_visitor(*this, v);
    }

    template <typename T> TypeVariant operator()(T const& a) const {
        return static_cast<bool>(a);
    }
} static constexpr to_bool{};

int main() {
    using V = TypeVariant;

    for (V v : { V{}, { 42 }, { 3.14f }, { true } }) {
        std::cout << v << " -> " << std::boolalpha << to_bool(v) << "\n";
    }
}
0 -> false
42 -> true
3.14 -> true
true -> true