Getting the address of an overloaded static function

Possible duplicate:
how to indicate a pointer to an overloaded function?

I have a library that has a class defined as:

struct ClassA { static ClassA foo(long); static ClassA foo(double); } 

I need to get the addresses of both of these functions. The code I'm trying to execute gives error C2440: cannot convert from 'overloaded function' to '...'

 ns::ClassA (ns::ClassA::*ClassA_foo1)(long) = &ns::ClassA::foo; ns::ClassA (ns::ClassA::*ClassA_foo2)(double) = &ns::ClassA::foo; 

I thought it might be a fact that they are static, but static both before and after the return type gives the same error.

+4
source share
3 answers

The fact that the function is overloaded is not really relevant. The real problem here is the difference between a function pointer and a pointer-member-pointer. I will give some examples without overloading.

Decision. Or remove static to define them as member functions. Or replace ns::ClassA::*ClassA_foo1 with *ClassA_foo1 . I think you want the last one. (But I really recommend that you use typedef , as others have already pointed out).

Consider these two:

 namespace ns { struct ClassA { static ClassA foo(long); }; } 

and

 namespace ns { struct ClassA { ClassA foo(long); }; } 

In the first case, foo is static and therefore is a typical function and can be stored in a function pointer:

 ns::ClassA (ClassA_foo1)(long) = &ns::ClassA::foo; 

If you remove static , then this is no longer a function, it is a member function. And pointers to function elements are different from pointers to functions, they must be executed with an object, which will be the this object on which the method is called.

The function pointer type includes the return type and the parameter type. But the type of the member-pointer function should also include the type of the this object - you do not expect that you can start the method from Circle for an object of type BankAccount .

Function pointer declaration:

  ReturnType (*variable_name) (PARAM1, PARAM2) 

Declaring a member pointer function:

  ReturnType (ThisObjectType::*variable_name) (PARAM1, PARAM2) 

This last line is interesting. At first glance, you might think that R (A::*v) (P1,P2) declares a normal function pointer and places the resulting variable v in area A But this is not so. Instead, it defines a member pointer function that works with objects of type A

+5
source

The problem you are observing is completely unrelated to the fact that the function is overloaded. You will get the same error for an unloaded function.

Static member functions have the usual type of function. Meanwhile, you are trying to interpret them as member-type functions. This results in a pointer type mismatch reported to you by the compiler. Here is a simple example that does not compile for the same reason.

 struct S { static void foo(); }; ... void (S::*p)() = &S::foo; // ERROR, pointer type mismatch 

In other words, your pointers are declared as pointers of type to a member pointer. Such pointers cannot contain the address of a static member function. The static member function and the non-static member function are beasts of a completely different nature. The corresponding pointer types are incompatible and cannot be converted to each other. This is the cause of your mistake.

Here's how it probably should have looked

 ns::ClassA (*ClassA_foo1)(long) = &ns::ClassA::foo; ns::ClassA (*ClassA_foo2)(double) = &ns::ClassA::foo; 

i.e. pointers on the left should be declared as regular function pointers, and not as member function pointers.

+3
source
 ns::ClassA (ns::ClassA::*ClassA_foo1)(long) = &ns::ClassA::foo; ns::ClassA (ns::ClassA::*ClassA_foo2)(double) = &ns::ClassA::foo; 

It looks like you are trying to set a couple of static members ClassA_foo1 and ClassA_foo2 in the file area. If so, this is not valid syntax. Syntax for defining a static member

 SomeType ClassName::member = initializer; 

It is best to use typedef to declare and define ClassA_foo1 and ClassA_foo2 :

 struct ClassA { typedef ClassA (*ClassALongGenerator) (long); typedef ClassA (*ClassADoubleGenerator) (double); static ClassALongGenerator ClassA_foo1; static ClassADoubleGenerator ClassA_foo2; }; 

then in the file area in some source file

 ns::ClassALongGenerator ClassA_foo1 = ns::ClassA::foo; ns::ClassADoubleGenerator ClassA_foo2 = ns::ClassA::foo; 
0
source

All Articles