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

使用推导式this的函数无法绑定到std::bind_front的问题求助

使用deducing-this的函数无法传入std::bind_front的问题分析

问题背景

尝试用deducing-this替代CRTP以减少模板代码,却遇到了无法将使用deducing-this的成员函数传入std::bind_front的编译错误。在Boost.Beast中常用bind_front_handler传递回调,但Connection类的回调改用deducing-this后无法正常绑定,测试环境为Clang 18.1.0。

示例代码

#include <iostream>
#include <functional>

struct A {
    void foo_deducing_this(this auto& self, int x) {
        self.bar(x);
    }
};

template <typename Deriv>
struct B {
    void foo_crtp(int x) {
        static_cast<Deriv *>(this)->bar(x);
    }
};

struct C : A, B<C> {
    void bar(int x) {
        std::cout << "number is " << x << "\n";
    }
};

void test(const std::function<void(int)>& f, int x) {
    f(x);
}

int main() {
    C c;

    c.foo_deducing_this(1);
    c.foo_crtp(2);
    c.bar(3);

    // 编译失败
    // test(std::bind_front(&C::foo_deducing_this, c), 5);
    
    test(std::bind_front(&C::foo_crtp, c), 6);
    test(std::bind_front(&C::bar, c), 7);
}

Boost.Beast回调场景示例

stream.async_read(buffer,
                  beast::bind_front_handler(&Connection::on_read,
                                             this->shared_from_this()));

问题原因

deducing-this语法定义的成员函数本质是模板函数:this auto& self会被编译器解析为模板参数,而非固定的对象类型。当尝试直接取&C::foo_deducing_this的地址时,编译器无法自动推断模板参数(即self的具体类型),而std::bind_front和beast::bind_front_handler都需要明确的、已实例化的函数类型,而非未解析的模板。

对比CRTP版本的foo_crtp:当B<C>实例化后,foo_crtp是一个具体的非模板成员函数,不存在参数推断问题,因此可以直接取地址传递。

解决方案

1. 显式指定模板参数

直接为deducing-this函数指定模板实参,让编译器实例化出具体的函数版本:

test(std::bind_front(&C::foo_deducing_this<C&>, c), 5);

在Boost.Beast场景中:

stream.async_read(buffer,
                  beast::bind_front_handler(
                      &Connection::on_read<Connection&>,
                      this->shared_from_this()));

2. 使用Lambda表达式包裹(推荐)

Lambda会自动推导调用时的类型,无需手动指定模板参数,写法更简洁:

test([&c](int x) { c.foo_deducing_this(x); }, 5);

在Boost.Beast场景中,结合shared_from_this使用:

stream.async_read(buffer,
                  [self = shared_from_this()](auto&&... args) {
                      self->on_read(std::forward<decltype(args)>(args)...);
                  });

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.27 04:54:55