5
void f()
{}

void test()
{
    auto fn_1 = f;
    auto fn_2 = &f;

    assert(fn_1 == fn_2); // OK

    fn_1();      // OK
    fn_2();      // OK
    (*fn_1)();   // OK
    (*fn_2)();   // OK
    (**fn_1)();  // OK
    (**fn_2)();  // OK
    (***fn_1)(); // OK
    (***fn_2)(); // OK
}

Are these behaviors explicitly defined by the C++ standard?

xmllmx
  • 39,765
  • 26
  • 162
  • 323

2 Answers2

1

Yes the ampersand is optional, they produce the same result.

An lvalue of function type T can be converted to a prvalue of type “pointer to T.” The result is a pointer to the function.55

I'm just gonna go ahead and say if your using c++11 you should be using std::function anyway it's much easier to understand and use.

aaronman
  • 18,343
  • 7
  • 63
  • 78
1

The issue at play here is that a function decays into a function pointer. The types of both of the variables fn_1 and fn_2 are void (*)(), i.e. "pointer to function taking no arguments and returning void". In the case of fn_1, the function f decays into a pointer to a function, while in the case of fn_2, you explicitly assign a pointer to a function to fn_2, and no decaying takes place.

Adam Rosenfield
  • 390,455
  • 97
  • 512
  • 589