size_t getAddress(F f) {
typedef void (fnType)(Ts...);
fnType ** fnPointer = f.template target<fnType*>();
if (fnPointer == nullptr) { //Must be member function.
//Code to get address of member function pointer
}
return (size_t)*fnPointer;
}
This function works fine for function pointers, but when I try to throw a bound Member function into the mix everything goes south.
I think this is because I template the function pointer as my normal function pointer type. But with a bound member function through std::bind this conversion fails.
I use this in my comparison operator for finding and removing functions from a vector.
EventObject<Ts...>& operator-=(const F& rhs) {
int i = 0;
for (auto const& value : callbacks) {
if (getAddress(rhs) == getAddress(value)) {
erase(i);
break;
}
i++;
}
return *this;
}
Google has failed me. I also imagine that this function will work for lambdas, sorta. As long as the compiler tries to optimize and combine similar lambda expressions.
So how do I get the address of a member function pointer through bind? Or is there a more optimal way? (Besides naming) Perhaps, should I wrap my function in a macro to store the enumerated type for comparisons instead?
Class information for reference:
template <typename...Ts>
class EventObject{
public:
typedef std::function<void(Ts...)> F;
typedef std::vector<F> CallBack;
Callback callbacks;
You should switch to using std::function
instead (update: it turns out you did already). std::function
is a general-purpose polymorphic function wrapper that will accept raw function pointers, binds, etc.
That way you have a standardized way to compare, which you need to pull off somehow but std::function
has ways to inspect the target, etc. : https://en.cppreference.com/w/cpp/utility/functional/function
Your signature becomes:
EventObject<Ts...>& operator-=(const std::function<R(Args...)>& rhs) {
Update: the issue with your target extraction is that you provide the signature of a plain function as the template argument - this will not work for the more 'advanced' function objects, binds etc. you have to provide the correct type so that:
target_type() == typeid(T)
see https://en.cppreference.com/w/cpp/utility/functional/function/target for more information and some relevant examples