我有一个代码结构,我在其中获取一个重载的函数指针,检查要执行的重载,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有多个“重载”,因此我无法使用第一个有效组合获得重载,因为可能没有。
我知道这个问题的确不是很好,但是找不到任何具体要点可以做得更好。我会根据您的喜好编辑问题以获取更多信息。
答案 0 :(得分:2)
使用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)
}
答案 1 :(得分:0)
不确定这是问题的关键,但是如果这条指令
auto to_invoke = static_cast<
void(*)(decltype(std::get<valid_args[P][0]>(Operand())))>(funcptr);
是尝试将具有特定签名的foobar()
函数的指针更改为具有相同foobar()
名称但具有不同签名的函数的指针...根本无法工作:指向函数的指针是指向函数的指针,你不能简单地将它转换为指向另一个函数的指针,希望拦截一个具有相同名称的函数,希望调用可以正常工作。
答案 2 :(得分:0)
删除此行:
auto to_invoke = static_cast<void(*)(decltype(std::get<valid_args[P][0]>(Operand())))>(funcptr);
你不想要一个指向函数的指针。您想要在一组操作数上调用一个函数,并且不需要指向函数的指针。
接下来,取代T& funcptr
取T&& to_invoke
。它不是指针;指针不代表多次重载。
#define RETURNS(...) \
noexcept(noexcept(__VA_ARGS__)) \
->decltype(__VA_ARGS__) \
{ return __VA_ARGS__; }
#define OVERLOADS_OF(...) \
[](auto&&...args) \
RETURNS(__VA_ARGS__( decltype(args)(args)... )
现在,如果您要将函数foo
的重载调度传递给OVERLOADS_OF(foo)
{/ 1}}。