Home > Software engineering >  The advantage of std::visit over if-else
The advantage of std::visit over if-else

Time:12-12

I have figured out that std::visit can be used the following way:

    std::visit([](auto&& arg) {
        using T = std::decay_t<decltype(arg)>;
        if constexpr (std::is_same_v<T, int>)
            std::cout << "int with value " << arg << '\n';
        else if constexpr (std::is_same_v<T, std::string>)
            std::cout << "std::string with value " << std::quoted(arg) << '\n';
        else 
            static_assert(always_false_v<T>, "non-exhaustive visitor!");
    }, v);

But instead, I figured I could also just use

    if(auto x = std::get_if<int>(&v))
        std::cout << " is int " << *x << std::endl;
    else if(auto x = std::get_if<std::string>(&v))
        std::cout << " is String " << *x << std::endl;
    else
        std::cout << "non-exhaustive visitor!" << std::endl;

The only disadvantage that I see right now is that I do not have a static message for when my matching is not exhaustive. Is there any other advantage of using std::visit that I am not seeing?

CodePudding user response:

Is there any other advantage of using std::visit that I am not seeing?

Yes. With std::visit you can use the built-in function overload resolution instead of matching against all of the types manually:

template<typename... Fs> struct Overload: Fs... { using Fs::operator()...; };

static_assert(visit(Overload{
    [](int) { return "int"; },
    [](std::string_view) { return "string_view"; },
    [](auto) { return "something else"; }
}, std::variant<int, std::string_view, bool, double>{42}) == "int"sv);

Also, visit might compile to faster code because of only one type match, but it should be checked whether the ifs-version gets its multiple matches optimized away.

  • Related