C++中如何将std::ostream的operator<<作为函数参数传递?
问题原因
你遇到的编译错误核心原因是std::ostream::operator<<是一组重载的成员函数,存在多个适配不同参数类型的实现,直接传递std::cout.operator<<时,编译器无法自动判断要选取匹配int参数的重载版本,因此无法推导模板参数Visitor的类型,触发编译错误。
解决方案
方案1:使用Lambda包装(最推荐,适配所有打印场景)
该方案不需要修改你已有的print模板,只需要在传参时用Lambda做一层轻量包装即可,完美适配你要求的通用性,可无缝对接std::cout、std::fout、printf等各类打印接口:
// 对接std::cout print([](int val) { std::cout << val; }, 5); // 对接printf print([](int val) { printf("%d", val); }, 5); // 对接std::ofstream std::ofstream fout("test.txt"); print([&fout](int val) { fout << val; }, 5);
该方案逻辑直观,无额外性能开销,还支持自定义打印格式,是最优选择。
方案2:显式指定重载版本(仅适用于成员函数指针场景)
如果你确实需要直接传递成员函数指针,可以显式指定要选择的重载版本,同时绑定std::cout实例即可:
#include <iostream> #include <functional> template <typename Visitor> void print(Visitor v, int value) { v(value); } int main(void) { // 显式指定要调用的operator<<重载类型:参数为int的成员函数 using OpPtr = std::ostream& (std::ostream::*)(int); // 绑定cout实例到成员函数指针 auto printer = std::bind(static_cast<OpPtr>(&std::ostream::operator<<), &std::cout, std::placeholders::_1); print(printer, 5); return 0; }
该方案灵活性较差,每更换一种参数类型都需要重新指定重载版本,通用性远低于Lambda方案。
内容的提问来源于stack exchange,提问作者Richard H. Nguyen
相关产品推荐
相关产品推荐

