【问题标题】:Get address of member function through std::bind?通过std::bind获取成员函数的地址?
【发布时间】:2019-02-20 11:56:32
【问题描述】:
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;
}

此函数适用于函数指针,但当我尝试将绑定的成员函数放入混合中时,一切都变南了。

我认为这是因为我将函数指针模板化为我的正常函数指针类型。但是对于通过 std::bind 绑定的成员函数,此转换失败。

我在比较运算符中使用它来从向量中查找和删除函数。

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 让我失望了。我也想象这个函数将适用于 lambdas,sorta。只要编译器尝试优化和组合类似的 lambda 表达式。

那么如何通过bind获取成员函数指针的地址呢?还是有更优化的方法? (除了命名)也许,我应该将我的函数包装在一个宏中以存储枚举类型以进行比较吗?

类信息供参考:

template <typename...Ts>
class EventObject{
public:
    typedef std::function<void(Ts...)> F;
    typedef std::vector<F> CallBack;
    Callback callbacks;

【问题讨论】:

  • 这看起来像是 XY 类型的问题。
  • 很难理解你的代码中发生了什么,但问题似乎是不可能转换任何类型的有状态函子(有状态的 lambda、与bind 绑定的成员函数等等) 到函数指针。使用std::functions 代替函数指针。

标签: c++ member-functions stdbind


【解决方案1】:

您应该改用std::function(更新:事实证明您已经这样做了)。 std::function 是一个通用的多态函数包装器,它将接受原始函数指针、绑定等。 这样你就有了一种标准化的比较方法,你需要以某种方式完成,但std::function 有方法检查目标等:https://en.cppreference.com/w/cpp/utility/functional/function

你的签名变成:

EventObject<Ts...>& operator-=(const std::function<R(Args...)>& rhs) {

更新:您的目标提取问题在于您提供了普通函数的签名作为模板参数 - 这不适用于更“高级”的函数对象、绑定等。必须提供正确的类型,以便:

target_type() == typeid(T)

查看https://en.cppreference.com/w/cpp/utility/functional/function/target了解更多信息和一些相关示例

【讨论】:

  • 抱歉添加了更多关于类的信息。我已经使用 std::function 了。
  • @StevenVenham 我更新了我的答案,为什么你的方法不起作用
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-01-09
  • 2021-04-27
  • 2011-12-28
  • 2013-01-08
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多