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 によると、そのコンストラクター が a への参照をstd::basic_ostream取るためです。これは、が渡された文字列を変更しないことを意味します。引用された参照は、渡された文字列 のコピーを作成するとさえ言っています。std::streamconststd::stringstd::basic_ostringstreamstd::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

ストリーム バッファを使用して、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()ただし、それをオーバーライドして正しいサイズ変更を行うことができます。

于 2015-03-12T18:29:56.367 に答える