【发布时间】:2023-03-23 04:16:01
【问题描述】:
我正在尝试从 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;
}
更新:捕获我正在使用的 lambda
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;
【问题讨论】:
-
似乎工作正常。您可能希望包含一个完整的示例,包括用法。显示实际失败的东西。
-
除此之外:您假设(由于未定义行为的痛苦)
std::functions 中的所有内容都是函数指针,这不是很明智,因为如果它们是,您可以使用函数指针而是键入,而不会遇到所有这些麻烦。