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

如何在模板函数中调用C++成员函数?(shared_ptr多线程场景)

正确调用带参数成员函数的后台线程模板实现

问题描述

尝试将类的std::shared_ptr传入run模板函数,在后台线程中执行带int参数的成员函数,但不清楚如何正确调用传入的成员函数指针。

现有代码

class MyA {
public:
    MyA() = default;
    void func(int) { /* ... */ };
};

class MyB {
public:
    MyB() = default;
    void func2(int) { /* ... */ };
};

auto myA = std::make_shared<MyA>();
auto myB = std::make_shared<MyB>();

run(myA, &MyA::func, 1, 5);
run(myB, &MyB::func2, 1, 3);

当前错误的run函数实现

template <typename C, typename F>
void run(std::shared_ptr<C> c, F f, int a, int b)
{
    std::thread([&c, &f, a, b]() {
        while (true) {
            // 此处写法错误,不知如何调用传入的成员函数
            c.f(a);

            std::this_thread::sleep_for(std::chrono::seconds(b));
        }
    }).detach();
}

解决方案

要正确实现,需注意两个核心要点:

  1. 成员函数指针的调用语法:必须通过对象指针调用,且要注意运算符优先级,需用括号包裹指针与函数指针的绑定
  2. 线程变量捕获方式:不能引用捕获std::shared_ptr和成员函数指针,线程detach后原变量可能销毁,会导致悬垂引用,必须值捕获

修正后的run函数实现:

#include <memory>
#include <thread>
#include <chrono>

template <typename C, typename F>
void run(std::shared_ptr<C> c, F f, int a, int b)
{
    // 值捕获变量,避免线程detach后出现悬垂引用
    std::thread([c, f, a, b]() {
        while (true) {
            // 正确调用成员函数指针:(对象指针->*成员函数指针)(参数)
            // 必须加括号,因为->*优先级低于函数调用
            (c->*f)(a);

            std::this_thread::sleep_for(std::chrono::seconds(b));
        }
    }).detach();
}

补充说明

  • 运算符优先级:->*的优先级低于函数调用(),如果不加括号,编译器会错误解析为c->*(f(a)),导致编译失败
  • 线程安全:如果成员函数会修改类的成员变量,需要添加std::mutex等同步机制保证线程安全
  • 对象生命周期:需确保shared_ptr指向的对象生命周期覆盖线程运行时间,避免线程运行时对象被销毁导致未定义行为

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.15 00:49:56