boost::variant применить static_visitor к определенным типам

У меня такой вариант:

typedef boost::variant<int, float, bool> TypeVariant;

И я хочу создать посетителя, который конвертирует int или же float введите в bool тип.


struct ConvertToBool : public boost::static_visitor<TypeVariant> {

    TypeVariant operator()(int a) const {
        return (bool)a;
    }

    TypeVariant operator()(float a) const {
        return (bool)a;
    }
};

Однако это дает мне сообщение об ошибке:

'TypeVariant ConvertToBool::operator ()(float) const': невозможно преобразовать аргумент 1 из 'T' в 'float'

Как правильно разрешить посетителю обращаться только к определенным типам?

1 ответ

Решение

Просто включите недостающую перегрузку:

Live On Coliru

#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";
    }
}

Обобщить

В более общих случаях вы можете предоставить перегрузку универсального шаблона:

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

Фактически, в вашем тривиальном случае это все, что вам нужно в любом случае:

Live On Coliru

#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
Другие вопросы по тегам