Casting Between Void * and a Pointer to Member Function

error: invalid conversion from method to void*

The language doesn't allow auto conversion of a pointer to a function to a void pointer.

Here's what the C++ Draft Standard (N3337) says about pointer conversion (emphasis mine):

4.10 Pointer conversions

2 An rvalue of type “pointer to cv T,” where T is an object type, can be converted to an rvalue of type “pointer to cv void.” The result of converting a “pointer to cv T” to a “pointer to cv void” points to the start of the storage location where the object of type T resides, as if the object is a most derived object (1.8) of type T (that is, not a base class subobject).

Functions are not objects. This is stated in:

1.8 The C+ + object model

1 The constructs in a C + + program create, destroy, refer to, access, and manipulate objects. An object is a region of storage. [Note: A function is not an object, regardless of whether or not it occupies storage in the way that objects do. ]

Object type is defined as:

3.9 Types

9 An object type is a (possibly cv-qualified) type that is not a function type, not a reference type, and not a void type.

Convert pointer to data member to void *

A pointer to non-static class member type is not the same as a object pointer type; they behave very differently. In fact, you cannot even dereference a pointer to member with *. To access a member through a pointer to member, you use the .* and ->* operators instead. If you could cast it to an object pointer type like this, what would happen, then, if you dereferenced it with *?

Only object pointer types have a standard conversion to void* (§4.10):

A prvalue of type "pointer to cv T," where T is an object type, can be converted to a prvalue of type "pointer to cv void".

They're so different that the standard even goes out of its way to make sure that the term "pointer" doesn't include pointers to non-static members (§3.9.2):

Except for pointers to static members, text referring to "pointers" does not apply to pointers to members.

Illegal operand error on a function pointer iterator

Member function pointers don't implement operator<, which is the default sorting function std::map uses.

Member function pointers only implement operator== and operator!= .

An easy way to fix this woud be to have a separate key and put the function pointer into the value of the map, e.g.:

std::map<int, std::pair<FuncPtr, float>>

or if you don't need the fast lookup of std::map, a simple vector would also work:

std::vector<std::pair<FuncPtr, float>>

An alternative approach would be to use the function pointer type as key:

using FuncPtr = void (Game::*)(int);

// Just a helper to get a unique type for each function pointer
template<FuncPtr ptr>
struct Tag {};

struct DelayedTrigger {
FuncPtr ptr;
float value;

DelayedTrigger() : ptr(nullptr), value(0.0f) {}
DelayedTrigger(FuncPtr _ptr, float _value) : ptr(_ptr), value(_value) {}
};

std::map<std::type_index, DelayedTrigger> funcDelayedTriggerMap;

void Game::PollProcessDelayedTriggers()
{
for (std::map<std::type_index, DelayedTrigger>::iterator it = funcDelayedTriggerMap.begin(); it != funcDelayedTriggerMap.end(); ++it)
{
float currentS = 1.0;
if (it->second.value < currentS)
{
(this->*(it->second.ptr))(0);
funcDelayedTriggerMap.erase(it->first);
}
}
}

This essentially uses the specific function pointer as a unique key.

You could then add new entries like this:

funcDelayedTriggerMap.emplace(typeid(Tag<&Game::DoIt>), DelayedTrigger{&Game::DoIt, 1.0f});
// or
funcDelayedTriggerMap[typeid(Tag<&Game::DoIt>)] = {&Game::DoIt, 1.0f};

And check if a function is present:

if(funcDelayedTriggerMap.contains(typeid(Tag<&Game::DoIt>))) {
// ...
}

This however only works if you know all the functions you want to use with the map at compile time.

Calling base class definition of virtual member function with function pointer

When you call a virtual method via a reference or a pointer you will always activate the virtual call mechanism that finds the most derived type.

Your best bet is to add an alternative function that is not virtual.



Related Topics



Leave a reply



Submit