16

std::function から関数のアドレスを見つけようとしています。

最初の解決策は次のとおりです。

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

しかし、それは (void ()) 署名を持つ関数でのみ機能します。署名が (void (Type &)) である関数が必要なので、やろうとしました

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

そして、「エラー - 関数スタイルのキャストまたは型の構築に '(' が必要です」というメッセージが表示されます

更新:メンバークラスのアドレスを取得する方法はありますか? 私が使用しているクラスメンバーの場合:

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;
}

更新:私が使用しているラムダをキャプチャするには

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;
4

2 に答える 2