首页 > 解决方案 > 如何获取指向重载函数的任何重载的指针,其重载未知?

问题描述

我有一个代码结构,我在其中获取一个重载函数指针,检查要执行的重载,static_cast指向正确重载的指针并运行它。

问题是,负责获取指向此函数的任何重载的指针的调用函数无法知道现有重载的列表。也就是说,这样的代码:

auto ptr = &foobar;
invoke_correct_overload<decltype(ptr)>(ptr);

无法工作,因为第一行不明确。有没有办法在第一行指定重载无关紧要,或者它应该是编译器发现的第一个重载?

语境

我有一个可变数量的std::variant,并且需要根据它们持有的值将它提供给不同的函数。我已经找到了一种使用 constexpr 数组来查找要执行的重载的方法,并且正在编写一个函数,该函数接受一个指向函数的指针,根据数组中的索引转换所有变体,然后执行它。

当前尝试

#define GENERAL_INTERFACE(SPE_FUNC, OPERANDS) do {\
        int valid_comb_index = evaluate_valid_types(valid_args_##SPE_FUNC, OPERANDS)); \
        constexpr [[maybe_unused]] auto foo = SPE_FUNC; \
        invoke_right_overload<valid_args_##SPE_FUNC.size(), \
                              valid_args_##SPE_FUNC[0].size() - 1, \                                   
                              valid_args_##SPE_FUNC, decltype(foo)> \                                                           
                              (valid_comb_index, OPERANDS,foo); \

template<std::size_t N, std::size_t P,
const std::array<std::array<int, 1>, N>& valid_args, typename T>
void invoke_right_overload(int valid_comb_index, 
std::vector<Operand> operands, T& funcptr) {
   if(valid_comb_index == P - 1) {
          auto to_invoke = static_cast<void(*)(decltype(std::get<valid_args[P][0]>(Operand())))>(funcptr);

          std::invoke(to_invoke, std::get<valid_args[P][0]>(operands[0]));
   }

   if constexpr (P - 1 == 0) return;

   invoke_right_overload<N, P - 1,  valid_args, T>(valid_comb_index, 
   operands, funcptr, apply_to);
   }

问题在于调用invoke_right_overload 的函数。对于 0、1、2 或 3 个操作数,invoke_right_overload 有多个“重载”,因此我无法使用第一个有效组合来获得重载,因为可能没有。

我知道这个问题的格式不是很好,但找不到任何具体点可以做得更好。我会尽可能多地编辑问题以获取更多信息。

标签: c++templatesg++c++17

解决方案


使用 lambda 而不是原始函数指针以及std::visit

void foo(int) { std::cout << "int\n"; }
void foo(double) { std::cout << "double\n"; }

int main() {
    auto f = [](auto... params) { foo(params...); };

    std::variant<int, double> v = 42;
    std::visit(f, v); // will call foo(int)
    v = 3.14;
    std::visit(f, v); // will call foo(double)
}

现场演示


推荐阅读