4

In this example code, func1 is the type of void (*)(int, double) and funky is the type of void(&)(int, double).

#include <iostream>

using namespace std;

void someFunc(int i, double j) {
    cout << i << ":" << j << endl;
} 

int main(int argc, char *argv[]) {

    auto func1 = someFunc; 
    auto& func2 = someFunc;

    cout << typeid(func1).name() << endl;
    cout << typeid(func2).name() << endl;

    func1(10, 20.0);
    func2(10, 30.0);
}

The output shows the difference:

PFvidE
FvidE
10:20
10:30

Practically, what is the difference between the two types?

prosseek
  • 182,215
  • 215
  • 566
  • 871
  • Internal representations are the same, but language level meanings are quite different – SwiftMango May 31 '15 at 18:49
  • "Syntactic sugar" rules of the language allow using them with identical syntax. But semantically they are different. For example, `auto& func2 = &someFunc;` will not compile, while `auto func1 = &someFunc;` will. Although using `auto` in this context will only obfuscate the difference. – AnT stands with Russia May 31 '15 at 18:52

2 Answers2

5

If you wanted to be able to assign a pointer to a function and then later change what that pointer points to then use auto fp = func. If not then use a reference auto& rp = func since you cannot reassign it:

#include <iostream>
using namespace std;

int funcA(int i, int j) {
    return i+j;
}

int funcB(int i, int j) {
    return i*j;
}

int main(int argc, char *argv[]) {
    auto fp = funcA;
    auto& rp = funcA;

    cout << fp(1, 2) << endl; // 3 (1 + 2)
    cout << rp(1, 2) << endl; // 3 (1 + 2)

    fp = funcB;
    //rp = funcB; // error: assignment of read-only reference 'rp'

    cout << fp(1, 2) << endl; // 2 (1 * 2)

    return 0;
}

I was trying to come up with a more practical example of why anyone would ever do this, below is some code that uses an array of pointers to call a function based on user input (any element of arr could also be changed during run time to point to another function):

#include <iostream>
using namespace std;

void funcA(int i, int j) {
    std::cout << "0: " << i << ", " << j << endl;
}

void funcB(int i, int j) {
    std::cout << "1: " << i << ", " << j << endl;
}

void funcC(int i, int j) {
    std::cout << "2: " << i << ", " << j << endl;
}

int main(int argc, char *argv[]) {
    if (argc < 2) {
        cout << "Usage: ./a.out <val>" << endl;
        exit(0);
    }

    int index = atoi(argv[1]);
    if (index < 0 || index > 2) {
        cout << "Out of bounds" << endl;
        exit(0);
    }

    void(* arr[])(int, int) = { funcA, funcB, funcC };
    arr[index](1, 2);

    return 0;
}
asimes
  • 5,749
  • 5
  • 39
  • 76
0
auto func1 = someFunc; 
auto& func2 = someFunc;

Say you have another function and you want func2 to point this other function

void function()
{
    cout<<"Hello world"<<endl;
}

So you do below

func2 = function();

All you get is compilation error. Reason being func2 is reference and once reference is initialized it cannot be changed.

HadeS
  • 2,020
  • 19
  • 36