Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is there an analogue of an object's `this`, but for functions?

I have searched the reference and a general web, but I am unable to find out, if it exists.

Is there a way to get a pointer to the current function in C++? It is so trivial, that it should exist.

In the perfect world I would want to find a way to get an std::function of current function, but even an old style pointer would do.

To clarify why it may be needed: I am thinking about recursion inside a Lambda function or even general recursion in a function, with the high potential of the name change in the future releases.

like image 467
v010dya Avatar asked Jan 26 '14 18:01

v010dya


2 Answers

There isn't, largely because there's no need for it. In the context of a (non-anonymous function) function, you always know where you stand - you can always use its name to refer to it or get its address. Unlike objects, where different ones have different addresses, ergo the need for this.

like image 78
Luchian Grigore Avatar answered Nov 15 '22 16:11

Luchian Grigore


In general you can't. For example, in a lambda that's convertible to raw function pointer, there's no (standard language) way to obtain that pointer inside the function.

However, you can obtain the function name as a raw string, via the macro __func__, except that only the newest versions of the compilers provide it with that macro name.

Also, if you are OK with non-portable code there are several compiler-specific introspection facilities (I just know they exist, but would have to google them for you to list them).


Addressing the question's newly added part, how to let a function be recursive and still support easy name change and/or lambdas.

One way is to use a std::function, but much easier (and possibly a bit more efficient) is to just define the recursive function as an internal implementation detail, e.g. in a namespace or in an inner class:

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

How to do the above with a lambda instead of a named function:

#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 );
}
like image 27
Cheers and hth. - Alf Avatar answered Nov 15 '22 16:11

Cheers and hth. - Alf