【发布时间】:2022-09-20 17:08:23
【问题描述】:
我需要实现一个函数来检索具有 n 个参数的重载成员函数的函数指针。所以例如对于以下课程:
struct Test
{
int func(int i1);
int func(int i1, int i2);
int func(int i1, int i2, int i3);
};
我需要检索Test::func 的一个特定重载。我已经有以下实现:
template<int Num> struct Overload {};
template<> struct Overload<0>
{
template<class Ret, class Class>
static auto from(Ret (*func)()) { return func; }
template<class Ret, class Class>
static auto from(Ret (Class::*meth)()) { return meth; }
template<class Ret, class Class>
static auto from(Ret (Class::*meth)() const) { return meth; }
};
template<> struct Overload<2>
{
template<class Ret, class Class, class Arg1, class Arg2>
static auto from(Ret (*func)(Arg1, Arg2)) { return func; }
template<class Ret, class Class, class Arg1, class Arg2>
static auto from(Ret (Class::*meth)(Arg1, Arg2)) { return meth; }
template<class Ret, class Class, class Arg1, class Arg2>
static auto from(Ret (Class::*meth)(Arg1, Arg2) const) { return meth; }
};
此实现按预期工作,但需要为每个参数计数单独实现。
据我了解,这需要https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2014/n4072.html 被拒绝,但我可能会遗漏一些东西。有没有办法从 C++17/C++20 中的模板参数Num 派生参数?
编辑:关于 cmets / 答案的一些说明
- 为什么不直接使用参数作为模板参数:
我已经为此目的提供了一个功能:
template<class... Args> struct OverloadArgs { template<class Ret> static auto from(Ret (*func)(Args...)) {return func;} ... };例如。对于 swizzling,我只是有多个具有不同 arg 计数的重载,指定
Overload<4>::from(&Test::swizzle)而不是OverloadArgs<int, int, int, int>::from(&Test::swizzle)要简洁得多- 这用于将函数/类包装到 Python。如 1) 中所述,在某些情况下,重载 arg 计数而不是 arg 类型会更简洁,这就是我想要两者兼有的原因。
-
出于好奇,您打算如何处理采用相同数量但不同类型参数的重载?
-
我有一个类似的实现,它直接允许用户指定 arg 类型:
template<class... Args> struct OverloadArgs -
看看
std::mem_fn。您可能只需要在其模板中指定函数签名,以便它可以执行重载决议。即auto memptr1 = std::mem_fn<int(int)>(&Test::func)和auto memptr2 = std::mem_fn<int(int, int)>(&Test::func)。 -
类型是否仅限于
int? (在这种情况下,std::index_sequence和 \"using always_t<I, T> = T;\" 可能会成功)。 -
类型不限于 int。通常它将是同一类型的 n 倍,因为对于不同的类型,
OverloadArgsimpl 可能更具可读性。