我希望std::ostringstream
修改我传递的字符串:
#include <string>
#include <iostream>
#include <sstream>
void My_Function(std::string& error_message)
{
std::ostringstream error_stream(error_message);
// For Nipun Talukdar:
/* Perform some operations */
if (/* operation failed */)
{
error_stream << "Failure at line: "
<< __LINE__
<< ", in source file: "
<< __FILE__
<< "\n";
}
return;
}
int main(void)
{
std::string error_message;
My_Function(error_message);
std::cout << "Error is: \""
<< error_message
<< "\"\n";
return 0;
}
使用上面的代码,error_message
的输出为空。
这是因为,according to cppreference.com,std::basic_ostream
的构造函数采用std::stream
对const
的 std::string
引用}。这意味着std::basic_ostringstream
不会修改传递给它的字符串。引用的参考文献甚至说std::ostringstream
将传递给它的字符串的副本。
为了解决这个问题,我改变了我的功能:
void My_Second_Function(std::string& error_message)
{
std::ostringstream error_stream;
error_stream << "Failure at line: "
<< __LINE__
<< "\n";
error_message = error_stream.str(); // This is not efficient, making a copy!
return;
}
是否有更有效的方法对字符串执行格式化输出,例如直接写入(即无需从流中复制)?
我使用的是Visual Studio 2010,,它不支持C ++ 11 。由于商店的考虑,升级到2013年的理由没有通过。所以我不能使用C ++ 11或C ++ 14的功能。
答案 0 :(得分:1)
使用流缓冲区并将put指针设置为字符串的内部数据:
struct nocopy : std::streambuf
{
nocopy(std::string& str)
{ this->setp(&str[0], &str[0] + str.size()); }
};
struct nocopy_stream : virtual private nocopy, std::ostream
{
nocopy_stream(std::string& str)
: nocopy(str)
, std::ostream(this)
{ }
};
void My_Function(std::string& error_message)
{
nocopy_stream error_stream(error_message);
error_stream << "Failure at line: "
<< __LINE__
<< "\n";
}
int main(void)
{
std::string error_message;
error_message.resize(1000);
My_Function(error_message);
std::cout << "Error is: \""
<< error_message
<< "\"\n";
}
对于此示例,error_message
必须设置为足够大的大小,因为我们不会覆盖overflow()
并且基类版本不执行任何操作。您可以覆盖它以执行正确的调整大小。