How do I pattern match (std::visit) std::any in C++?

In C++, you can use std::any to hold any type of value, but pattern matching it directly isn't straightforward as it is with variants. However, you can achieve this with std::visit in combination with std::optional or by using custom visitor classes.

A common way to handle this is to store your types in a std::variant and then use std::visit for pattern matching. Since std::any doesn't directly support visitation, you would typically convert it to std::variant. Below is an example of how to achieve this:


#include <iostream>
#include <any>
#include <variant>
#include <string>

using ValueType = std::variant<int, double, std::string>;

struct Visitor {
    void operator()(int value) const {
        std::cout << "Integer: " << value << std::endl;
    }

    void operator()(double value) const {
        std::cout << "Double: " << value << std::endl;
    }

    void operator()(const std::string& value) const {
        std::cout << "String: " << value << std::endl;
    }
};

int main() {
    std::any value = 42; // Can be int, double, or string.

    // Cast std::any to the appropriate type and use std::variant
    if (value.type() == typeid(int)) {
        std::visit(Visitor{}, ValueType{std::any_cast<int>(value)});
    } else if (value.type() == typeid(double)) {
        std::visit(Visitor{}, ValueType{std::any_cast<double>(value)});
    } else if (value.type() == typeid(std::string)) {
        std::visit(Visitor{}, ValueType{std::any_cast<std::string>(value)});
    } else {
        std::cout << "Unsupported type" << std::endl;
    }

    return 0;
}
    

C++ std::any std::variant std::visit pattern matching C++ programming