9

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.

abyss.7
  • 13,882
  • 11
  • 56
  • 100
v010dya
  • 5,296
  • 7
  • 28
  • 48
  • 1
    You can use functions name as its pointer. And it has nothing to do with this – qwm Jan 26 '14 at 18:57
  • 2
    A function is not instanciated, so there is no `this`. You can still use the normal pointer to your function (Even in a templated function this should work) – user1781290 Jan 26 '14 at 18:57
  • 1
    I have to say, though the concept is not necessary, I still love the idea. For example a recursive function doesn't have to know its own name. If you rename it, you don't have to touch the body of the function. – Karoly Horvath Jan 26 '14 at 19:04
  • @KarolyHorvath I was thinking about recursion actually. But i'll live without it. – v010dya Jan 26 '14 at 19:08
  • Interesting question. I'd support a proposal to add this in C++17. – Lightness Races in Orbit Jan 26 '14 at 19:21
  • @LightnessRacesinOrbit: actually a similar thing for class defintions would be a real boon... most modern languages don't force you to retype the class name several times. calling the constr/destr by class name was clearly a bad design choice, and will probably never fixed. anyway, this is offtopic. – Karoly Horvath Jan 26 '14 at 19:26
  • 1
    @KarolyHorvath: Related: http://stackoverflow.com/q/21143835/560648 – Lightness Races in Orbit Jan 26 '14 at 19:32
  • Not really related, but kind of an interesting side question: If you want it as a string, in C you can use `__FUNCTION__`, or `__WFUNCTION__` – C.J. Jan 26 '14 at 19:12

4 Answers4

13

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.

Luchian Grigore
  • 253,575
  • 64
  • 457
  • 625
4

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 );
}
Cheers and hth. - Alf
  • 142,714
  • 15
  • 209
  • 331
  • 2
    Out of interest, why `auto main() -> int` but `void foo( int const x )`? Just kicking the tyres, or is there some clever implication of the different styles? – Steve Jessop Jan 26 '14 at 19:41
  • @SteveJessop: there is clever implication. :) one has an expression result, the other has not. thus they're differentiated in some languages, e.g. Pascal `function` versus `procedure`. – Cheers and hth. - Alf Jan 26 '14 at 20:49
  • Cool, thanks. So the convention breaks down if you write a function template returning a `decltype` (or other dependent type) that may or may not be `void` according to template arguments? ;-) That is to say, a few miscellaneous procedures might be defined using the function style, but otherwise you can tell the difference at a glance. – Steve Jessop Jan 26 '14 at 20:55
  • @SteveJessop; re "breaks down" in special case, yes, but if you're doing that then it reeks of design fault. ;-) simply don't. that's also the reason why some languages differentiate these syntactically, and why the C language's conflation of them is generally known as a Really Bad language design error. – Cheers and hth. - Alf Jan 26 '14 at 20:59
2

If the purpose is just to obtain a std::function object, you might use the function name itself:

#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

but this isn't immune to name changing unfortunately. You might also encapsulate the function into something else to get rid of name changing:

#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

Marco A.
  • 43,032
  • 26
  • 132
  • 246
0

you can do this:

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

insert a reference to the function into a global map and retrieve it from within the function. There's still room for encapsulating the map but I hope the idea is clear.

In c++ function is not a first class citizen so you will have to work a bit to get the function's reference.

Ezra
  • 1,401
  • 5
  • 15
  • 33
  • If you want to get a reference to a function then you need to use a function pointer and assign a value to it. Can you do it in any other way? – Ezra Jan 26 '14 at 19:23
  • Reread the question: "Is there a way to get a pointer to the **current** function in C++?" – kotlomoy Jan 26 '14 at 19:25
  • sure, now you have to pass that reference into the function, either through a parameter, or through global variable. I would wrap it with a macro. – Ezra Jan 26 '14 at 19:27
  • I am here to learn but I still didn't see any other way of doing it. Not that I have ever needed such a thing. – Ezra Jan 26 '14 at 19:29
  • At least complete your example code - "pass that reference into the function". Now the answer is incomplete – kotlomoy Jan 26 '14 at 19:33
  • *"In C++ function is not a first class citizen so"* Isn't? So what are functors, lambdas, function pointers, etc, compared to Java `doSomethingStupidWhichInvolvesOnlyAFunction` interfaces like `Runnable`? – Manu343726 Jan 26 '14 at 19:42
  • @kotolmoy, agreed and added. – Ezra Jan 26 '14 at 19:46
  • As far as I know, a first class citizen means to be an object. Neither of what you have suggested is an object. – Ezra Jan 26 '14 at 19:48
  • @Ezra Functor is a contraction of "Function Object".... If you don't know C++, don't answer questions about it. Lambdas are really unnamed functors (Closures). Function pointers are normally wrapped inside functors in proper C++. So three of three – Manu343726 Jan 26 '14 at 19:50
  • @Manu343726 A functor is a pattern. A class with operator(). you can instantiate objects from it but they will never be object of that function, just object of that class, which potentially can have many other members beside of its operator() – Ezra Jan 26 '14 at 19:53
  • The term is *concept*, not pattern. And everithing in C++ are concepts. Thats how the language works. – Manu343726 Jan 26 '14 at 19:55
  • For example: Have you seen the `Iterator` class/interface in any part of C++? No. Thats why `iterator` [is a concept](http://en.cppreference.com/w/cpp/iterator), defined as *"Everything which can be dereferenced, incremented, etc"*. That is, everything that looks like an iterator (Duck typing). **The same applies to functions and function objects**. – Manu343726 Jan 26 '14 at 20:02