0

我想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为空。

这是因为,根据 cppreference.com,它的构造函数 std::basic_ostream采用std::streamaconst引用 a 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;
}

是否有更有效的方法来执行格式化输出到字符串,例如直接写入(即不必从流中复制)?

我正在使用不支持 C++11的 Visual Studio 2010 。由于店铺考虑,升级到2013的理由没有通过。所以我不能使用 C++11 或 C++14 的特性。

4

1 回答 1

1

使用流缓冲区并将放置指针设置为字符串的内部数据:

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()并且基类版本什么也不做。但是,您可以覆盖它以进行正确的调整大小。

于 2015-03-12T18:29:56.367 回答