79387929

Date: 2025-01-26 03:33:24
Score: 0.5
Natty:
Report link

Basic function for your operation is as follows:

template<typename L, typename R>
std::any Add(std::any l, std::any r) {
    return std::any(std::any_cast<L>(l) + std::any_cast<R>(r));
}

Note that above function uses c++ rules for finding a common type. You may wish to look at std::common_type or specializations.

Other than that, this problem is related to multiple dispatch. Popular languages usually don't bother with it and use single dispatch for all dynamically typed values (virtual functions) and sometimes end up with quirks such as __radd__ in python. You may also be interested in reading about as dynamic cast in C# for overloads

As discussed case is relatively simple, it can be achieved by having a std::map:

std::map<
    std::pair<std::type_index, std::type_index>,
    std::any (*)(std::any, std::any)
>

For such cases I prefer not to bother myself with metaprogramming and would write a codegen file, but for the sake of staying in c++ let's just use macros (and have 2N repetitions instead of N^2). In the end any solution will produce N^2 entities in the resulting machine code

#define IT(L, R) { \
    {std::type_index(typeid(L)), std::type_index(typeid(R))}, \
    &Add<L, R> \
},
#define FOR_T(R) \
    IT(short, R) IT(int, R) IT(double, R)

FOR_T(short) FOR_T(int) FOR_T(double)

Complete example below:

#include <any>
#include <map>
#include <typeindex>

template<typename L, typename R>
std::any Add(std::any l, std::any r) {
    return std::any(std::any_cast<L>(l) + std::any_cast<R>(r));
}

#define IT(L, R) { \
    {std::type_index(typeid(L)), std::type_index(typeid(R))}, \
    &Add<L, R> \
},
#define FOR_T(R) \
    IT(short, R) IT(int, R) IT(double, R)

using operator_dispatch_key = std::pair<std::type_index, std::type_index>;

std::map<operator_dispatch_key, std::any (*)(std::any, std::any)> all_ops = {
    FOR_T(short) FOR_T(int) FOR_T(double)
};

#include <iostream>

int main() {
    auto l = std::any(int(1));
    auto r = std::any(double(2.5));

    auto l_t = std::type_index(l.type());
    auto r_t = std::type_index(r.type());
    auto res = all_ops[std::make_pair(l_t, r_t)](std::move(l), std::move(r));

    std::cout
        << res.type().name()
        << ' '
        << std::any_cast<double>(res)
        << std::endl
        ;

    return 0;
}

Program returned: 0
Output: d 3.5

PS as your operators are "internal" you can just use an array of such maps for them. It won't work for type ids of std::any because they are not sequential

Reasons:
  • Blacklisted phrase (1.5): any solution
  • Long answer (-1):
  • Has code block (-0.5):
  • Low reputation (0.5):
Posted by: kp2pml30