问题描述
假设我有这个:
using sftype = void (*)(bool real,sftype target);
我知道这会导致递归调用,但实现应该是这样的:
void someFunc(bool real,sftype another = nullptr) {
return;
}
我希望能够将此函数存储在 sftype var = someFunc;
之类的变量中。
我知道可以通过多种方式解决问题,例如:
using sftype = void (*)(bool real,void *const target);
void someFunc(bool real,void *const target = nullptr) {
return;
}
void main() {
sftype var = someFunc;
}
然而,它看起来像个骗子。
是的,我知道有一个关于类似主题的古老问题:Can I declare a function that can take pointer to itself as an argument?。 但是,也许现在在新版本的 C++ (C++20) 中,有一个漂亮的解决方案,而且不会损失性能(例如,使用类)。
如何漂亮地(并且不损失性能)创建一个将自身作为参数的函数类型?
解决方法
您可以使用 struct
来包装函数指针,然后您可以在 struct
/using
中使用该 typedef
:
struct sftype_impl;
using sftype = void (*)(bool real,sftype_impl target);
struct sftype_impl
{
sftype_impl(sftype ptr)
: ptr(ptr)
{
}
void operator()(bool real,sftype_impl target)
{
ptr(real,target);
}
operator bool()
{
return ptr;
}
sftype ptr;
};
void foo(bool real,sftype_impl target)
{
if (target)
{
target(real,nullptr);
}
}
void bar(bool real,nullptr);
}
}
int main()
{
foo(true,bar);
}
在大多数情况下,结构应该大部分或完全优化掉。
,在 C++ 中不可能声明一个函数,它接受一个自己类型的函数作为参数。
您可以拥有一个带有成员函数的函子,该成员函数将函子的实例作为参数,例如:
struct Func {
void operator()(Func f){ /*...etc... */ }
};
,
正如 Eljay 在评论中提到的,您可以使用函子。它可以是一个 lambda。为了清楚起见,这里还有手写的:
#include <iostream>
struct foo {
void operator()(foo& f){ }
};
int main() {
foo f;
f(f);
auto g = [](auto h,bool call) -> void {
if (call) h(h,false);
std::cout << "hello";
};
g(g,true);
}