Jenix
Jenix

Reputation: 3076

About Function Pointer in C++

  1. Do these lines mean the same? Both works without any warning messages!

int (*pFunc)() = func1;     // I learned this is right.
int (*pFunc)() = &func1;        // Works well with an ampersand too.
  1. Why do I have to put an ampersand in this case? Without it, doesn't work!

int (CMyClass::*pMemberFunc)() = &CMyClass::memberFunc1;
  1. Why do I have to specify namespace for functions in Classes even if the type of the function pointer matches exactly?

int (*pMemberFunc)() = CMyClass::memberFunc1;       // Compiler error
int (*pMemberFunc)() = &CMyClass::memberFunc1;      // Compiler error
  1. Why can't I specify namespace in this case?

namespace myNamespace {
    int func1() {}
}

int (myNamespace::*pFunc)() = myNamespace::func1;       // Compiler error
int (myNamespace::*pFunc)() = &myNamespace::func1;      // Compiler error

int (*pFunc)() = &myNamespace::func1;       // Works!

Upvotes: 0

Views: 227

Answers (2)

Cui Heng
Cui Heng

Reputation: 1285

1) about Q1, looking at the following code, as the func1 is a right-value of the function, so with or without "&" doesn't change the actual function address. Look at the following code:

#include <stdio.h>

void foo(){
   printf("foo called\n");
}


int main(){
   printf("%p\n", foo);
   printf("%p\n", &foo);
   void (*FUNC) ();
   FUNC = foo;
   FUNC();
   printf("address %p\n", FUNC);
   printf("address %p\n", &FUNC);
   return 0;
}

output is

0x101406eb0
0x101406eb0
foo called
address 0x101406eb0
address 0x7fff5e7f9a80

Q2 & Q3 ) Pointers to Member Functions Are Not Pointers You can refer it here https://www.safaribooksonline.com/library/view/c-common-knowledge/0321321928/ch16.html

Upvotes: 1

ZaldronGG
ZaldronGG

Reputation: 1004

Your first question, legalese of the Standard:

A pointer to member is only formed when an explicit & is used and its operand is a qualified-id not enclosed in parentheses. [Note: that is, the expression &(qualified-id), where the qualified-id is enclosed in parentheses, does not form an expression of type “pointer to member.” Neither does qualified-id, because there is no implicit conversion from a qualified-id for a non-static member function to the type “pointer to member function” as there is from an lvalue of function type to the type “pointer to function” (4.3). Nor is &unqualified-id a pointer to member, even within the scope of the unqualified-id’s class. —end note ]

While it seems inconsistent at first, I do like the fact that it makes the semantics for pointers to members (be them functions or not) equivalent. This certainly has benefits when dealing with templates and decltype.

For the second question, you scope the pointer variable with CMyClass because yours is not a simple "() -> int" function: memberFunc1() is implicitly passed a CmyClass* argument you normally refer to as "this".

If you could truly pass nothing, you'd be missing information (and possibly crash) for the method to do its job correctly. If you're accustomed to "delegates" in other languages, do remember these can optionally store a "Target" pointer to the "this" object if the method is not static/global.

As for the third, it's a free standing function, so it's truly () -> int, but you're attempting to scope your pointer to the namespace, when in fact you're not declaring your variable inside the namespace block.

While the namespace certainly alters how symbols are searched for, it doesn't affect the convention call of the function at all.

Upvotes: 1

Related Questions