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

使用std::async调用含shared_ptr的模板类成员函数遇编译错误求助

解决std::async调用持有shared_ptr的模板类成员函数的问题

我来帮你拆解一下问题出在哪,以及怎么修复:

首先看你出错的那段代码里的几个关键问题:

1. shared_ptr创建时的语法错误

你写的auto foo2 = std::make_shared<Foo<std::shared_ptr<Bar>>>;少了调用括号,正确的写法应该是auto foo2 = std::make_shared<Foo<std::shared_ptr<Bar>>>();——不过即使你补上括号,这里还有第二个更核心的问题。

2. 传递给std::async的对象指针类型不匹配

foo2是std::shared_ptr<Foo<std::shared_ptr<Bar>>>类型,如果你传&foo2,相当于把一个std::shared_ptr<...>*(指向智能指针的指针)传给了成员函数,但成员函数set_data需要的是Foo<std::shared_ptr<Bar>>*类型的this指针,类型不匹配直接导致模板参数推导失败。

3. 变量名笔误

你定义了auto br = std::make_shared<Bar>;,但后面调用时用的是bar,这也是编译报错的一个小诱因。

修复后的完整代码

你后来给出的修复版本是完全正确的,这里再明确一下逻辑:

#include "./foo.h"
#include <memory>
int main (int argc, char **argv) {
    // 直接在栈上创建Foo对象,避免智能指针的额外层级,简化指针传递逻辑
    Foo<std::shared_ptr<Bar>> foo2;
    // 正确创建Bar的shared_ptr并初始化数据
    auto bar = std::make_shared<Bar>();
    bar->data = 2.5;

    // 传递foo2的地址作为this指针,参数bar的类型正好匹配set_data的参数要求
    auto fut2 = std::async(std::launch::async, &Foo<std::shared_ptr<Bar>>::set_data, &foo2, bar);
    fut2.wait();
    // get()返回shared_ptr<Bar>,直接访问其data成员即可
    std::cout << fut2.get()->data << std::endl;
    return 0;
}

如果你一定要用shared_ptr管理Foo对象

如果你的场景里必须用std::shared_ptr<Foo<std::shared_ptr<Bar>>>来持有Foo实例,调用std::async时有两种简洁的写法:

auto foo2 = std::make_shared<Foo<std::shared_ptr<Bar>>>();
auto bar = std::make_shared<Bar>();
bar->data = 2.5;

// 写法1:用get()获取Foo对象的原始指针传递给async
auto fut2 = std::async(std::launch::async, &Foo<std::shared_ptr<Bar>>::set_data, foo2.get(), bar);

// 写法2:直接传递shared_ptr,std::async会自动处理this指针绑定
auto fut2 = std::async(std::launch::async, &Foo<std::shared_ptr<Bar>>::set_data, foo2, bar);

总结一下,问题的核心是传递给std::async的对象指针类型和成员函数期望的this指针类型不匹配,加上一些语法笔误,最终导致模板参数推导失败。当模板的参数是shared_ptr时,并没有特殊的语法要求,只是要注意智能指针本身的层级,不要把指向智能指针的指针错误传递进去。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.13 08:44:15