是否存在对象的“this”的类比,但对于函数?

时间:2014-01-26 18:55:00

标签: c++ this function-pointers

我搜索了参考文献和一般网络,但我无法找到,如果它存在。

有没有办法在C ++中获取指向当前函数的指针?它是如此微不足道,它应该存在。

在完美世界中,我想找到一种方法来获得当前函数的std::function,但即使是旧式指针也可以。

澄清为什么可能需要它:我正在考虑Lambda函数内的递归,甚至是函数中的一般递归,在将来的版本中名称更改的可能性很高。

4 个答案:

答案 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;
}

http://ideone.com/4C9gc5

但不幸的是,这对名字改变并不是免疫的。您也可以将函数封装到其他内容中以消除名称更改:

#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;
}

http://ideone.com/5Xb0ML

答案 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 ++中,函数不是一等公民,所以你需要工作一点才能得到函数的参考。

相关问题