typedef functions question

I know how to use typedef, but I don't understand the following piece of code:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
#include "std_lib_facilities.h"

typedef double F(double);

struct A
{
	A() { }
	A(F arg) { n = int(arg); }
	int n;
};

double example_f(double) { return 1; }

int main()
{
	A obj(log);
	A obj2(cos);
	A obj3(example_f);
	cout << obj.n << "\n";
	cout << obj2.n << "\n";
	cout << obj3.n << "\n";
	keep_window_open();
}


I particularly don't understand typedef double F(double);. I know the output results are erroneous. I just need someone to explain to me how this thing works. Have in mind that I am a beginner so please explain it as simple as possible (some of you might ask why am I asking such a question, well it's in the book I am reading so I want to know what it is). Thanks in advance to anyone who replies!
Last edited on
It is a type-id for a function declaration that has return value of the type double and one parameter of the type double.
Consider the following simple example

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#include <iostream>

typedef double F(double);. 

int main()
{
   F my_func;  // here identifier my_func is declared as having type of double( double)

   std::cout << my_func( 10.0 ) << std::endl;
}

double my_func( double x )
{
   return x * x;
}
Last edited on
Thanks for the quick reply. But I don't understand this line of code:

F my_func;

What does it do? Where would you use a type-id for a function declaration? And what's the difference between:

1
2
3
4
// ... //
F my_func;
std::cout << my_func( 10.0 ) << std::endl;
// ... // 


and

1
2
3
// ... //
std::cout << my_func( 10.0 ) << std::endl;
// ... // 


It still outputs the same result.
> Where would you use a type-id for a function

A typedef just creates an alias for a type (another name by which the type can be known).
A typeid is different from a type alias.

Where would we use it? Typically, when we want to access a function indirectly through a reference or a pointer. And we want to simplify the syntax; make the code more readable.

For example, std::qsort() needs to access a function through a pointer passed to it at runtime.
http://en.cppreference.com/w/cpp/algorithm/qsort

This
1
2
void qsort( const void *ptr, std::size_t count, std::size_t size,
            int (*comp)(const void *, const void *) );


And this:
1
2
3
typedef int comparison_function( const void *, const void * ) ; 
void qsort( const void *ptr, std::size_t count, std::size_t size,
            comparison_function* comp );

are equivalent.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
#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
}


http://ideone.com/yWyV7C
Last edited on
@benbalach
What does it do? Where would you use a type-id for a function declaration?


Sometimes declarations of functions can be very compound. In this case it is better to use a typedef name for example as a template parameter.

Consider sample code

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
#include <iostream>
 
typedef double Function( double, double );
 
template <Function F>
struct Math
{
    double x, y;
    double Invoke() const { return ( F( x, y ) ); }
};
 
double Add( double x, double y ) { return ( x + y ); }
double Multiply( double x, double y ) { return ( x * y ); }
double Divide( double x, double y ) { return ( x / y ); }
 
int main()
{
    Math<Add> m1 = { 10, 20 };
    
    std::cout << m1.Invoke() << std::endl;
    
    Math<Multiply> m2 = { 10, 20 };
    
    std::cout << m2.Invoke() << std::endl;
    
    Math<Divide> m3 = { 10, 20 };
    
    std::cout << m3.Invoke() << std::endl;
}
Last edited on
Topic archived. No new replies allowed.