#include <iostream>
double foo( double d ) { return d*2 ; }
double bar( double d ) { return d/2 ; }
int main()
{
typedef double F(double); // F is an alias for double(double)
// ie. a unary function taking a double and returning a double}
F& fn1 = foo ; // type of 'fn1' is reference to F
// ie. a reference to a unary function taking a double and returning a double}
// and it is initialized to refer to foo
std::cout << fn1(1.234) << '\n' ; // foo(1.234)
F& fn2 = bar ; // type of 'fn2' is reference to F
// ie. a reference to a unary function taking a double and returning a double}
// and it is initialized to refer to bar
std::cout << fn2(1.234) << '\n' ; // bar(1.234)
F* pfn = nullptr ; // type of 'pfn' is pointer to F
// ie. a pointer to a unary function taking a double and returning a double}
// and it is initialized to be a null pointer
pfn = &foo ; // pfn now points to foo
std::cout << (*pfn)(1.234) << '\n' ; // foo(1.234)
pfn = &bar ; // pfn now points to bar
std::cout << (*pfn)(1.234) << '\n' ; // bar(1.234)
// the above two lines can also be written as:
pfn = bar ; // pfn now points to bar - address of is implied
std::cout << pfn(1.234) << '\n' ; // bar(1.234) - dereference of pointer is implied
}