2

I'm trying to construct a std::variant out of a boost::variant. In practice, I'm trying to define a function with the following signature:

template <typename... Types>
std::variant<Types...>
boostvar2stdvar(boost::variant<Types...> input);

I've seen the answer to this question, but in that case it's converting a tuple to a std::variant, not a boost::variant. I need my function to take a boost::variant directly. Is there an easy way to do that?

cnewbie
  • 177
  • 5
  • Do you know what `boost::apply_visitor` does, and how to use it? – Sam Varshavchik Nov 08 '22 at 13:23
  • Honestly I've never used more than `boost::get<>`, but hopefully I can learn it @SamVarshavchik – cnewbie Nov 08 '22 at 13:25
  • @SamVarshavchik I tried up to now, but honestly I'm lost. I've somehow understood the first examples, but I don't see how to use it – cnewbie Nov 08 '22 at 18:34
  • Sorry to hear that, I'm sure that there are plenty of textbooks or tutorials, that teach how to use Boost's advanced templates. And it's unclear what "the first examples" means. I see no examples at https://www.boost.org/doc/libs/1_80_0/doc/html/boost/apply_visitor.html – Sam Varshavchik Nov 08 '22 at 19:34
  • I meant these ones: https://theboostcpplibraries.com/boost.variant How would you use the boost::apply_visitor the fill the variant? @SamVarshavchik – cnewbie Nov 08 '22 at 19:50
  • Pretty much how it's shown there, except that the visitors return the `std::variant`, instead of `void`, and each visitor constructs the `std::variant` from the visited value and return it, and `apply_visitor` then returns the constructed variant. – Sam Varshavchik Nov 09 '22 at 00:21

1 Answers1

3

As others have pointed out, you can visit all elements types and return the desired variant from there:

template <typename... Types> auto b2std(boost::variant<Types...> const& input) {
    return boost::apply_visitor(
        [](auto const& v) -> std::variant<Types...> { return v; }, input);
}

When used like this

auto x = b2std(boost::variant<int, std::string, double>{"hello world"});

Then type of x matches the expected:

static_assert(
    std::is_same_v<std::variant<int, std::string, double>, decltype(x)>);

Live

See it Live On Coliru

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

template <typename... Types> auto b2std(boost::variant<Types...> const& input) {
    return boost::apply_visitor(
        [](auto const& v) -> std::variant<Types...> { return v; }, input);
}

int main() {
    auto x = b2std(boost::variant<int, std::string, double>{"hello world"});
    static_assert(
        std::is_same_v<std::variant<int, std::string, double>, decltype(x)>);
}
sehe
  • 374,641
  • 47
  • 450
  • 633