Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Getting the address of an overloaded static function [duplicate]

Tags:

c++

Possible Duplicate:
how to specify a pointer to an overloaded function?

I have a library which has a class defined as:

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

I need to get the addresses of both of those functions. The code I am currently trying 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 the fact that they are static, but placing static either before or after the return type gives the same error.

like image 844
Austin Wagner Avatar asked Aug 31 '12 18:08

Austin Wagner


2 Answers

The fact that the function is overloaded is not really relevant. The real issue here is the difference between a function-pointer and a member-function-pointer. I'll run through some examples without overloading.

Solution: Either remove the static, in order to define them as member-functions. Or else replace ns::ClassA::*ClassA_foo1 with *ClassA_foo1. I think you want the latter. (But I actually recommend you use typedef, as others have already suggested).

Consider these two:

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

and

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

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

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

If you remove the static, then it is not a function any more, it's a member function. And pointers-to-member-functions are different from pointers-to-functions, they must be executed with an object that will be the this object on which the method is called.

The type of a function pointer includes the type of the return value and the type of the parameters. But the type of a pointer-to-member-function must also include the type of the this object - you wouldn't expect to be able to run a method from a Circle on an object of type BankAccount.

Declaring a pointer-to-function:

 ReturnType (*variable_name) (PARAM1, PARAM2)

Declaring a pointer-to-member-function:

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

This last line is the interesting one. At first glance, you might think that R (A::*v) (P1,P2) declares a normal function-pointer and places the resulting variable v into the A scope. But it does not. Instead it defines a pointer-to-member-function which operates on objects of type A.

like image 184
Aaron McDaid Avatar answered Oct 20 '22 00:10

Aaron McDaid


The problem that you are observing has absolutely nothing to do with the fact that the function is overloaded. You'd get the same error for a non-overloaded function.

Static member functions have ordinary function type. Meanwhile, you are trying to interpret them as functions of member-function type. This leads to pointer type mismatch reported to you by the compiler. Here's a simple example that will fail to compile for the very 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 pointer-to-member-function type. Such pointers cannot hold the address of a static member function. A static member function and a non-static member function are beasts of completely different nature. The corresponding pointer types are not compatible and not convertible to each other. That's the reason for your error.

This is how it was probably supposed to look

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

i.e. the pointers on the left-hand side should be declared as ordinary function pointers, not as member function pointers.

like image 4
AnT Avatar answered Oct 19 '22 23:10

AnT