C++ trying to get function address from a std::function

c++, function, pointers, std

Solution

You need to use the `template` keyword when you call target:

#include <functional>
#include <iostream>

template<typename T>
size_t getAddress(std::function<void (T &)> f) {
    typedef void (fnType)(T &);
    fnType ** fnPointer = f.template target<fnType*>();
    return (size_t) *fnPointer;
}

void foo(int& a) {
    a = 0;
}

int main() {
    std::function<void(int&)> f = &foo;
    std::cout << (size_t)&foo << std::endl << getAddress(f) << std::endl;
    return 0;
}

Hint: When you have problems with C++ syntax, I suggest you use `clang++` to compile your code. If you play around with how your write the code it will usually point you in the write direction to fix the error (when it can figure out what you are doing).

I also suggest that you use variadic templates to make your function a bit more general:

template<typename T, typename... U>
size_t getAddress(std::function<T(U...)> f) {
    typedef T(fnType)(U...);
    fnType ** fnPointer = f.template target<fnType*>();
    return (size_t) *fnPointer;
}

Problem

i'm trying to find the address of a function from a std::function. The first solution was: ``` size_t getAddress(std::function<void (void)> function) { typedef void (fnType)(void); fnType ** fnPointer = function.target<fnType *>(); return (size_t) *fnPointer; } ``` But that only works for function with (void ()) signature, since i need for function that signature are (void (Type &)), i tried to do ``` template<typename T> size_t getAddress(std::function<void (T &)> function) { typedef void (fnType)(T &); fnType ** fnPointer = function.target<fnType *>(); return (size_t) *fnPointer; } ``` And i get "Error - expected '(' for function-style cast or type construction" Update: Is any way to capture member class address? for class members i'm using: ``` template<typename Clazz, typename Return, typename ...Arguments> size_t getMemberAddress(std::function<Return (Clazz::*)(Arguments...)> & executor) { typedef Return (Clazz::*fnType)(Arguments...); fnType ** fnPointer = executor.template target<fnType *>(); if (fnPointer != nullptr) { return (size_t) * fnPointer; } return 0; } ``` Update: To capture lambda i'm using ``` template <typename Function> struct function_traits : public function_traits<decltype(&Function::operator())> { }; template <typename ClassType, typename ReturnType, typename... Args> struct function_traits<ReturnType(ClassType::*)(Args...) const> { typedef ReturnType (*pointer)(Args...); typedef std::function<ReturnType(Args...)> function; }; template <typename Function> typename function_traits<Function>::function to_function (Function & lambda) { return static_cast<typename function_traits<Function>::function>(lambda); } template <typename Lambda> size_t getAddress(Lambda lambda) { auto function = new decltype(to_function(lambda))(to_function(lambda)); void * func = static_cast<void *>(function); return (size_t)func; } std::cout << getAddress([] { std::cout << "Hello" << std::endl;}) << std::endl; ```

Original source