Order of definition for function signatures in C++

lancery

I have a table of function pointers, and I am trying to determine whether the order of defining the function signatures matters. Looking at my example below, I am wondering why Method 1 doesn't compile, even though its function pointer type can be determined via decltype. I'd like to know what can be done to make Method 1 work. Any ideas? Thanks.

// Method 1
typedef struct FOO_FUNCS
{
    void( WINAPI * pfnFoo) ();
} FOO_FUNCS;
typedef decltype(&FOO_FUNCS::pfnFoo) PFN_FOO;

// Method 2
typedef void (WINAPI* PFN_BAR)();
typedef struct BAR_FUNCS
{
    PFN_BAR pfnBar;
} BAR_FUNCS;

class FooBarClass
{
public:
    static void WINAPI Foo()
    {
        cout << "Foo" << "\n";
    }
    static void WINAPI Bar()
    {
        cout << "Bar" << "\n";
    }
};

int _tmain(int argc, _TCHAR* argv[])
{
    void* pfnFoo = reinterpret_cast<void*>(FooBarClass::Foo);
    reinterpret_cast<PFN_FOO>(pfnFoo) (); <= = this gives me "error C2440 : 'reinterpret_cast' : cannot convert from 'void *' to 'PFN_FOO'"

    void* pfnBar = reinterpret_cast<void*>(FooBarClass::Bar);
    reinterpret_cast<PFN_BAR>(pfnBar) ();
}
Angew is no longer proud of SO

After expanding typedefs and decltype, PFN_FOO is a pointer to member of FOO_FUNCS, the type of the member being pointer to void WINAPI (). You cannot convert between a pointer to member and a void*. That's why you're getting the error.


I am not sure, but I believe you may have been looking for one of these:

typedef decltype(FOO_FUNCS().pfnFoo) PFN_FOO;

typedef decltype(&FOO_FUNCS().pfnFoo) PFN_FOO;

(In the general case, you'd prefer to use std::declval<FOO_FUNCS>() instead of just FOO_FUNCS() in the above, since that does not require an accessible default constructor).

Or perhaps the simplest (thanks to @Jarod42):

typedef decltype(FOO_FUNS::pfnFoo) PFN_FOO;

Here is what each of the typedefs does in more detail:

decltype(FOO_FUNCS().pfnFoo)

The expression is FOO_FUNCS().pfnFoo. That is, create a default-constructed FOO_FUNCS object and access its data member pfnFoo. decltype() applied to such an expression yields the type of the data member, which is void( WINAPI * ) (). That's a pointer to a WINAPI function taking no parameters and returning void.

decltype(&FOO_FUNCS().pfnFoo)

The expression is &FOO_FUNCS().pfnFoo. That is, create a default-constructed FOO_FUNCS object, access its data member pfnFoo and get its address (in memory). The type of this is "pointer to type of pfnFoo;" that means this decltype is equivalent to decltype(FOO_FUNCS().pfnFoo) *. So it's void( WINAPI * * ) () - a pointer to a pointer to a WINAPI function taking no parameters and returning void.

decltype(FOO_FUNCS::pfnFoo)

The expression is FOO_FUNCS::pfnFoo. That is, name the data member pfnFoo of class FOO_FUNCS. decltype() yields the type of this data member, which is again void( WINAPI * ) () - a pointer to a WINAPI function taking no parameters and returning void.

And your original one:

decltype(&FOO_FUNCS::pfnFoo)

The expression is &FOO_FUNCS::pfnFoo. That is, take the pointer to member (sometimes imprecisely called "member pointer") pfnFoo of class FOO_FUNCS. The type is void (WINAPI (FOO_FUNCS::*)*) () - a pointer to member of class FOO_FUNCS, where the member has type pointer to a WINAPI function taking no parameters and returning void.

The last one is fundamentally different - the other just play around with different ways of accessing the member as a variable (through a temporary, through qualified name), a physical piece of memory if you will. The last one treats it as a "logical" member, as an "offset" within the class. It's the same fundamental difference as between a pointer (T*) and a pointer to member of class X (T X::*).

Collected from the Internet

Please contact [email protected] to delete if infringement.

edited at
0

Comments

0 comments
Login to comment

Related

From Dev

Function signatures in C++ templates

From Dev

is Haskell sensitive to order in a function definition?

From Dev

Standard way of shortening C++ function signatures

From Dev

Definition of a function in a C program

From Dev

C function definition/prototype

From Dev

Function definition in C struct?

From Dev

C function definition and declaration

From Dev

C++ Pointer to a member function of any class with matching function signatures

From Dev

function definition in BNF C grammar

From Dev

c, function definition following struct

From Dev

Find function definition in C++

From Dev

Weird declaration and definition of a function in C

From Dev

Elegant function definition in C++

From Dev

Find function definition in C++

From Dev

function definition in BNF C grammar

From Dev

Elegant function definition in C++

From Dev

Incompatible anonymous Function Signatures in C# using lambda

From Dev

C - Mismatched function prototype and definition for "static" function

From Dev

Is the 'main' function classified as a function definition in C?

From Dev

Force specific function signatures

From Dev

Function signatures in julia

From Dev

Generic function signatures

From Dev

JavaScript function signatures in WebSharper

From Dev

Why does the order of a function definition change the output binary?

From Dev

Why does the order of a function definition change the output binary?

From Dev

Mixing pointers and references in function definition in C++

From Dev

What encompasses a function definition in C++?

From Dev

C using a forward declaration within a function definition

From Dev

Preprocessor macro overriding function definition in c++

Related Related

HotTag

Archive