Search code examples
c++lambdadiscriminated-union

How do I reduce an std::variant to one value?


I have a C++ 17 std::variant. How can I reduce it to a single instance of one type using lambdas?

I am looking for something like this:

std::variant<int, std::string> v = getIntOrString();

std::string x = reduce(
  v, 
  [](int i) {
    return "It's an int: " + std::to_string(i);
  }, 
  [](std::string i) {
    return "It's a string: " + i;
  });

Solution

  • Building on the example at cppreference, you'd use std::visit:

    #include <variant>
    #include <string>
    #include <iostream>
    
    template<class... Ts> struct overloaded : Ts... { using Ts::operator()...; };
    template<class... Ts> overloaded(Ts...) -> overloaded<Ts...>;
    
    int main() {
        using v_type = std::variant<int, std::string>;
        v_type v1{1}, v2{"2"};
    
        auto v_to_str = overloaded{
            [](int i) { return std::to_string(i) + " was an int"; },
            [](std::string const& s) { return s + " was already a string"; }
        };
    
        std::cout << std::visit(v_to_str, v1) << '\n'
                  << std::visit(v_to_str, v2);
    
    }
    

    Live Example