> 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