Pointer to Member Functions (is "&" required?)

N

Nimmi Srivastav

When I was learning C, I learned that the data type of a function name
by itself is a function pointer. For example

int
someFunction(char* str)
{
....
}


....
int (*fPtr) (char *) = someFunction;
....



I was, therefore, extremely surprised (while reading about pointers to
non-static member functions) when I saw that in C++, you need to
supply the address operator in front of the function name. That is,
the above statement will be something like this:

int (*fPtr) (char *) = &someFunction;


To explain what I am saying, let me take the liberty to include a
small code snippet from "C++ FAQs Second Edition" by Marshall Cline et
al.

FAQ 38.04 (How is an array of pointers to non static member functions
declared?)

class Fred {
public:
void f(int i);
void g(int i);
void h(int i);
};

....
typedef void (Fred::*FredMemberPtr)(int);
....

FredMemberPtr array[3] = {&Fred::f, &Fred::g, &Fred::h};
....


According to me, the above statement should have been something like
this:
FredMemberPtr array[3] = {Fred::f, Fred::g, Fred::h};


Why is the address operator (&) needed in this case at all? Kindly
explain. Is there a difference between C and C++ in this respect?

Thanks,
Nimmi
 
J

Jerry Coffin

When I was learning C, I learned that the data type of a function name
by itself is a function pointer.

That's correct.

[ ... ]
I was, therefore, extremely surprised (while reading about pointers to
non-static member functions) when I saw that in C++, you need to
supply the address operator in front of the function name.

That's also correct -- basically put, Bjarne screwed up, and the
committee didn't fix his mistake. AFAICT, Bjarne's reasoning was that
since he apparently normally used the '&' when taking the address of a
normal function, that he should require it when taking the address of a
member function. Therefore, in C++ taking the address of a member
function _requires_ the '&' in front of the name, even though it would
be trivial to specify the language so it wasn't required, and I don't
believe the ampersand makes parsing easier either.

[ ... ]
Why is the address operator (&) needed in this case at all?

Because the standard says it is. There's no other reason.
Kindly
explain. Is there a difference between C and C++ in this respect?

Yes, there are a number of differences. One is that C doesn't have
member functions.
 
K

Kevin Goodsell

Jerry said:
That's also correct

But only for member functions, right? The address-of operator is still
optional for non-member functions, isn't it?

-Kevin
 
G

Gianni Mariani

Kevin said:
But only for member functions, right? The address-of operator is still
optional for non-member functions, isn't it?

Yep - I think you're right. Only member functions require operator & to
get the address.

A piece of opinion, I have no problem with requiring the address of
operator for member functions. I think code written without it are a
little more difficult to read, it is however unfortunate that there is a
inconsistantcy for not needing the & operator on non-member functions
but if anyone cares, they have the option of using the & operator on
those as well.
 
J

Jack Klein

When I was learning C, I learned that the data type of a function name
by itself is a function pointer. For example

int
someFunction(char* str)
{
...
}


...
int (*fPtr) (char *) = someFunction;
...

The same syntax produces the identical results in C++
I was, therefore, extremely surprised (while reading about pointers to
non-static member functions) when I saw that in C++, you need to
supply the address operator in front of the function name. That is,
the above statement will be something like this:

int (*fPtr) (char *) = &someFunction;


To explain what I am saying, let me take the liberty to include a
small code snippet from "C++ FAQs Second Edition" by Marshall Cline et
al.

FAQ 38.04 (How is an array of pointers to non static member functions
declared?)

class Fred {
public:
void f(int i);
void g(int i);
void h(int i);
};

...
typedef void (Fred::*FredMemberPtr)(int);
...

FredMemberPtr array[3] = {&Fred::f, &Fred::g, &Fred::h};
...


According to me, the above statement should have been something like
this:
FredMemberPtr array[3] = {Fred::f, Fred::g, Fred::h};

Why should we care what it should be "according to you"? We have ISO
international standards so we do not have to depend on people's
opinions, even yours.
Why is the address operator (&) needed in this case at all? Kindly
explain. Is there a difference between C and C++ in this respect?

Yes, there is a difference between C and C++ in this respect. C++
requires use of the address-of operator ("&") to take the address of a
non-static member function. C, on the other hand, does not have
member functions, either static or non-static. So it does not define
the syntax of taking the address of something that does not exist in
the language.
Thanks,
Nimmi

Perhaps Bjarne's intent was to emphasize the difference between member
functions and free-standing, C compatible functions. To keep
programmers from forgetting the significant differences between the
two, or the fact that they are not compatible with each other nor
convertible to each other.

Or perhaps it was merely a style preference on Dr. Stroustrup's part,
as one other reply suggests.

The use of the ampersand is required by the C++ standard. The reason
that this requirement is part of the standard is irrelevant in this
group. You could purchase Stroustrup's book "Design and Evolution of
C++", although off-hand I can't remember what it says about this.

If you think this matter is such a serious handicap to writing correct
C++ programs that it should be changed in a future version of the C++
standard, post your comment to comp.std.c++.

--
Jack Klein
Home: http://JK-Technology.Com
FAQs for
comp.lang.c http://www.eskimo.com/~scs/C-faq/top.html
comp.lang.c++ http://www.parashift.com/c++-faq-lite/
alt.comp.lang.learn.c-c++ ftp://snurse-l.org/pub/acllc-c++/faq
 
J

Jerry Coffin

[ requirement to use '&' to take the address of a function ]
But only for member functions, right? The address-of operator is still
optional for non-member functions, isn't it?

Yes, that's correct.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,774
Messages
2,569,598
Members
45,152
Latest member
LorettaGur
Top