我搜索了参考文献和一般网络,但我无法找到,如果它存在。
有没有办法在C ++中获取指向当前函数的指针?它是如此微不足道,它应该存在。
在完美世界中,我想找到一种方法来获得当前函数的std::function
,但即使是旧式指针也可以。
澄清为什么可能需要它:我正在考虑Lambda函数内的递归,甚至是函数中的一般递归,在将来的版本中名称更改的可能性很高。
答案 0 :(得分:13)
没有,主要是因为没有必要。在(非匿名函数)函数的上下文中,您始终知道自己的位置 - 您始终可以使用其名称来引用它或获取其地址。与不同的地址不同的对象不同,需要this
。
答案 1 :(得分:4)
一般情况下你不能。例如,在可转换为原始函数指针的lambda中,没有(标准语言)方法在函数内获取该指针。
但是,您可以通过宏__func__
将函数名称作为原始字符串获取,但只有最新版本的编译器为其提供该宏名称。
另外,如果你对不可移植的代码没问题,那么有几个特定于编译器的内省工具(我只知道它们存在,但是必须谷歌它们才能列出它们。)
解决问题新增加的部分,如何让函数递归,并且仍然支持简单的名称更改和/或lambdas。
一种方法是使用std::function
,但更简单(并且可能更高效)是将递归函数定义为内部实现细节,例如,在命名空间或内部类中:
#include <iostream>
using namespace std;
void foo( int const x )
{
struct Recursive {
inline static void foo( int const x )
{
cout << x << ' ';
if( x > 0 ) { foo( x - 1 ); }
}
};
Recursive::foo( x );
cout << endl;
}
auto main() -> int
{
foo( 3 );
}
如何使用lambda而不是命名函数执行上述操作:
#include <iostream>
using namespace std;
auto main() -> int
{
auto const foo = []( int const x ) -> void
{
struct Recursive {
inline static void foo( int const x )
{
cout << x << ' ';
if( x > 0 ) { foo( x - 1 ); }
}
};
Recursive::foo( x );
cout << endl;
};
foo( 3 );
}
答案 2 :(得分:2)
如果目的只是获取 std :: function 对象,您可以使用函数名称本身:
#include <iostream>
#include <functional>
using namespace std;
void functionA(int a);
void functionA(int a)
{
cout << "Thanks for calling me with " << a << endl;
if(a == 22)
return;
std::function<void(int)> f_display = functionA;
f_display(22);
}
int main() {
functionA(1);
return 0;
}
但不幸的是,这对名字改变并不是免疫的。您也可以将函数封装到其他内容中以消除名称更改:
#include <iostream>
#include <functional>
using namespace std;
void functionA(int a)
{
cout << "Thanks for calling me with " << a << endl;
}
template <typename F>
void encapsulateFunction(F f, int val)
{
std::function<void(int)> f_display = f;
// f_display now points to the function encapsulated
f_display(val);
}
int main() {
encapsulateFunction(functionA, 22);
return 0;
}
答案 3 :(得分:0)
你可以这样做:
std::map<string, boost::any> functions;
int foo(int x) {
int (*fp)(int) = boost::any_cast<int (*)(int)>(functions[__func__]);
return x;
}
int main(int argc, char* argv[])
{
int (*fooPointer)(int) = foo;
boost::any fp = fooPointer;
functions["foo"] = fp;
...
}
将对函数的引用插入到全局映射中,并从函数中检索它。仍然有封装地图的空间,但我希望这个想法很清楚。
在c ++中,函数不是一等公民,所以你需要工作一点才能得到函数的参考。