You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何使用std::bind绑定纯虚函数接口的成员方法?

问题描述

我们有如下类层次结构:

class Add3Interface {
  virtual int add3 (const int&) const = 0;
};

class Add3: public Add3Interface {
  virtual int add3 (const int& arg) const override {
    return arg + 3;
  }
};

我希望绑定add3方法,用于std::views::transform这类场景。绑定具体类Add3的方法可以正常运行:

const Add3 myAdder{};
const auto myFun = std::bind(&Add3::add3, myAdder, std::placeholder::_1);

但我的场景中无法访问具体类型,只能通过Add3Interface接口操作,尝试以下代码时编译器报错:

auto foo(Add3Interface& myAdder) {
    const auto myFun = std::bind(&Add3Interface::add3, myAdder,
                                 std::placeholders::_1);
    // ...
}

错误信息:

/usr/include/c++/11/tuple:238:13: error: cannot declare field ‘std::_Head_base<0, Add3Interface, false>::_M_head_impl’ to be of abstract type ‘Add3Interface’

我试过用typeid解决但出现语法错误,虽然可以用lambda实现:

const auto myFun = [&myAdder] (const auto& arg) { return myAdder.add3(arg); };

但从语义上更偏好使用std::bind,请问该如何实现?

解决方案

问题出在std::bind的参数传递方式上:当你直接传入myAdder(Add3Interface&类型)时,std::bind会默认拷贝这个参数,但Add3Interface是抽象类,无法实例化,自然不能拷贝,这就是报错的原因。

要解决这个问题,你需要让std::bind保存对象的引用而非拷贝,使用std::ref(或std::cref如果对象是const引用)来包装参数:

auto foo(Add3Interface& myAdder) {
    const auto myFun = std::bind(&Add3Interface::add3, std::ref(myAdder),
                                 std::placeholders::_1);
    // 使用myFun...
}

如果myAdder是const引用,就用std::cref:

auto foo(const Add3Interface& myAdder) {
    const auto myFun = std::bind(&Add3Interface::add3, std::cref(myAdder),
                                 std::placeholders::_1);
    // 使用myFun...
}

这样std::bind内部会保存一个引用包装器,不会尝试拷贝抽象类对象,就能正常绑定虚方法,后续调用时会自动转发到实际的派生类实现。

内容的提问来源于stack exchange,提问作者antonio

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.11 11:38:14