> const double *(*p1)(const double *, int) = f1;
> I am just mind boggled of how this looks. I can see that "const double *" represents that it is a ptr of type double,
> but the name (*p1) yet again confuses me.
Let us look at this from first principles.
int foo(double) ;
foo is a function which takes one parameter of type
double and returns a value of type
int.
foo has a type; it is 'unary function taking a parameter of type double and returning an int' or simply
int(double)
int bar(double) ;
foo and
bar are of the same type.
1 2 3
|
int* baz(double) ;
int *baz(double) ;
int * baz(double) ;
|
baz is also a function, but the type of
baz is different; it is
int*(double), it returns a pointer to
int.
It does not matter how you place white space while writing baz, the * binds to the left.
Now, say, we wand to define a pointer to a function which can point to foo.
The type of the ptr that we need is 'pointer to
int(double)'
ie. 'pointer to unary function taking a parameter of type double and returning an int'
This won't do at all:
int *ptr(double) ;
Here,
ptr is of the same type as
baz; the * binds to the
int; we might as well have written
int* ptr(double) ;
Instead, we want the * to bind to
ptr; to say that
ptr is a pointer.
We can do this in two ways.
One, create a type alias for the type of the function foo:
1 2 3
|
typedef int type_of_foo(double) ;
using type_of_foo = int(double) ; // C++11
using type_of_foo = decltype(foo) ; // C++11
|
type_of_foo is an alias, another name by which we can refer to
int(double), the type of the function.
And now, we can write
type_of_foo* ptr = &foo ; // type of ptr is 'pointer to int(double)'
ptr is a pointer to a function, and it is initialized to point to
foo.
ptr = &bar ; this too is fine,
bar is a function of the same type, and
ptr now points to
bar.
The other (somewhat clumsier) way is to use parantheses to change the binding of the *
int (*ptr)(double) = &foo ; // type of ptr is 'pointer to int(double)'
Because of the paranthesis, the * binds to
ptr and not to
int.
> The program compiles but logically, would this be valid?
> Since in this example it returns a type int * instead of a const int *?
For an implicit conversion, a (top level)
const qualifier may be added.
If
T is some type, there is an implicit conversion from
T* to
const T*
1 2 3
|
int i = 7 ;
int* p = &i ;
const int* pc = p ; // fine, conversion adds the const qualifier
|
However, a
const qualifier can't be dropped implicitly.
p = pc ; // *** error, conversion requires dropping the const qualifier