解析std::bind作为std::shared_ptr删除器的编译错误
咱们直接拆解问题核心:你遇到的编译错误,本质是**std::shared_ptr的删除器签名和你绑定后的函数不匹配**。
错误根源分析
std::shared_ptr要求自定义删除器是一个可调用对象,且只能接受一个参数——也就是要被销毁的对象指针。但你的std::bind写法用了std::placeholders::_2占位符,导致绑定后的函数期望调用者传入两个参数,完全不符合shared_ptr的调用逻辑,这才触发了那些晦涩的编译断言错误。
看你的print函数签名:
void print(std::string string1, std::string* string2)
你用std::bind(print, foo, std::placeholders::_2)绑定后,生成的可调用对象会等待调用者传入第二个参数(对应_2),但shared_ptr在调用删除器时只会传入一个指针参数,两者完全不兼容。
修正后的代码
把占位符改成std::placeholders::_1,让shared_ptr传入的指针正确对应到print的第二个参数,同时我还修复了一个输出小问题(原代码输出的是指针地址而非字符串内容):
#include <functional> #include <iostream> #include <memory> #include <string> inline void print(std::string string1, std::string* string2) { std::cout << string1 << " " << *string2 << std::endl; delete string2; } class class1 { public: std::string foo{"Hello"}; std::shared_ptr<std::string> foo2; class1(); }; class1::class1() { // 用_1占位符对应print的第二个参数(要删除的指针) auto boundFunc = std::bind(print, foo, std::placeholders::_1); foo2 = std::shared_ptr<std::string>(new std::string("world"), boundFunc); } int main() { class1 test; // 可以手动触发删除器验证效果:test.foo2.reset(); }
关键修改点
- 占位符修正:将
_2改为_1,确保shared_ptr传入的指针被正确传递给print的string2参数,匹配删除器的调用要求。 - 输出逻辑修复:原代码中
std::cout << string2输出的是指针内存地址,改成*string2才能打印实际的字符串内容。
额外优化建议
如果不想拷贝foo字符串,可以用std::ref(foo)绑定引用(这里foo和foo2都是class1的成员,生命周期一致,完全安全):
auto boundFunc = std::bind(print, std::ref(foo), std::placeholders::_1);
内容的提问来源于stack exchange,提问作者Ishq
相关产品推荐
相关产品推荐

