如何在C++中定义支持ostringstream式参数的函数?
在C++中实现目标调用方式的方法
可以实现你想要的直接调用语法,核心是让"Error on line " << iLineNumber这类表达式合法,并能传递给foo函数。以下是具体实现方案:
方案原理
原生C++中,const char*(字符串字面量)没有operator<<运算符来支持和其他类型(如int、std::string)的链式输出,因此"Error on line " << iLineNumber本身是非法的。我们需要自定义全局运算符和包装类,让这类表达式返回一个可链式调用的流对象,最终传递给foo。
完整实现代码
#include <sstream> #include <iostream> #include <string> // 流包装类,用于链式收集输出内容 class StreamBuilder { public: std::ostringstream oss; // 重载<<运算符,支持任意类型的链式输出 template<typename T> StreamBuilder& operator<<(const T& val) { oss << val; return *this; } // 支持转换为std::string,方便直接使用内容 operator std::string() const { return oss.str(); } }; // 全局<<运算符,处理字符串字面量开头的链式调用 template<typename T> StreamBuilder operator<<(const char* str, const T& val) { StreamBuilder sb; sb.oss << str << val; return sb; } // 最终的foo函数,接收StreamBuilder对象并处理内容 void foo(const StreamBuilder& sb) { // 这里可以替换成你的实际业务逻辑,比如打印、日志写入等 std::cout << "输出内容:" << sb.oss.str() << std::endl; } // 测试代码 int main() { int iLineNumber = 25; std::string strName = "Alice"; // 按照你想要的方式调用foo foo("Error on line " << iLineNumber); foo("name " << strName << " is Invalid"); return 0; }
代码说明
- StreamBuilder类:内部封装
std::ostringstream,重载operator<<实现链式输出,同时提供std::string类型转换,方便获取最终拼接的字符串。 - 全局operator<<:专门处理字符串字面量与其他类型的第一个
<<操作,返回StreamBuilder对象,后续的<<操作会调用StreamBuilder自身的重载运算符。 - foo函数:接收
StreamBuilder对象,可直接通过sb.oss.str()获取拼接后的完整字符串,执行你的业务逻辑。
另一种简化方案(逗号传参)
如果你能接受用逗号分隔参数而非<<,可以用C++11的可变参数模板实现更简洁的版本:
#include <sstream> #include <iostream> #include <string> void foo(const std::string& msg) { std::cout << "输出内容:" << msg << std::endl; } template<typename... Args> void foo(Args&&... args) { std::ostringstream oss; // 折叠表达式拼接所有参数 (oss << ... << std::forward<Args>(args)); foo(oss.str()); } // 调用方式 int main() { int iLineNumber = 25; std::string strName = "Alice"; foo("Error on line ", iLineNumber); foo("name ", strName, " is Invalid"); return 0; }
内容的提问来源于stack exchange,提问作者Marek Krzeminski
相关产品推荐
相关产品推荐

