7

文字列ストリームを受け取り、次のようにするメソッドを作成することは可能ですか?

void method(string str)
void printStringStream( StringStream& ss)
{
    method(ss.str());
}

そして、このように呼び出すことができます

stringstream var;
printStringStream( var << "Text" << intVar << "More text"<<floatvar);

<<演算子を調べたところ、オブジェクトが返されているように見えますが、ostream&読み取りがthis間違っているか、正しく実装されていない可能性があります。

本当に必要なのは、文字列として連結して関数に渡すクリーンな方法です。私が見つけた最もクリーンなものはstringstreamオブジェクトでしたが、それでもまだ多くのことが望まれています。

ノート:

Visual Studio 2010を実行しているため、多くのc++11回答を使用できません(意志に反しますが、それでも)

私はアクセスできるBoostので、それに夢中になります。

この混乱を一掃する限り、私はカスタムメソッドに反対しません。

編集:

@Mooing Duckの回答と@PiotrNycz構文を組み合わせることで、次のようなコードを作成するという目標を達成しました。

try{

    //code

}catch(exception e)
{   
    printStringStream( stringstream() << "An exception has occurred.\n"
                            <<"    Error: " << e.message 
                            <<"\n If this persists please contact "<< contactInfo
                            <<"\n Sorry for the inconvenience");
}

これは私が望んでいたのと同じくらいきれいで読みやすいです。

うまくいけば、これは他の人がメッセージを書くのを片付けるのに役立つでしょう。

4

5 に答える 5

8

ああ、ちょっと時間がかかりました。はすべてのostreamタイプoperator<<に対してオーバーロードされた無料の関数であるため、を返しません。あなたが言うように、を返します。std::stringstreamstd::ostream

void printStringStream(std::ostream& ss)

明らかに、generalにはメンバーがostreamありませんが、ストリーム全体を別のストリームにコピーする魔法の方法があります。.str()

std::cout << ss.rdbuf();

これは、コンパイルして正常に実行されることを示す完全なコードへのリンクですhttp://ideone.com/DgL5V

編集

関数に文字列が本当に必要な場合は、いくつかの解決策を考えることができます。

まず、ストリーミングを個別に行います。

stringstream var;
var << "Text" << intVar << "More text"<<floatvar;
printStringStream(var);

2番目:ストリームを文字列にコピーします(パフォーマンスの問題の可能性があります)

void printStringStream( ostream& t)
{
    std::stringstream ss;
    ss << t.rdbuf();
    method(ss.str());
}

3番目:他の関数にもストリームを取得させる

于 2012-09-20T19:55:40.947 に答える
3

std::stringstreamのラッパーを作成します。operator <<この新しいクラスでは、必要なものを何でも定義できます。

class SSB {
public:
   operator std::stringstream& () { return ss; }

   template <class T>
   SSB& operator << (const T& v) { ss << v; return *this; }
   template <class T>
   SSB& operator << (const T* v) { ss << v; return *this; }
   SSB& operator << (std::ostream& (*v)(std::ostream&)) { ss << v; return *this; }
   // Be aware - I am not sure I cover all <<'s       
private:
   std::stringstream ss;
};

void print(std::stringstream& ss)
{
    std::cout << ss.str() << std::endl;
}

int main() {
  SSB ssb;
  print (ssb << "Hello" << " world in " << 2012 << std::endl);
  print (SSB() << "Hello" << " world in " << 2012 << std::endl);
}
于 2012-09-20T20:24:55.937 に答える
3

ストリームに挿入できるオブジェクトを簡単に作成できるように、これらのクラスはすべてにオーバーロードoperator<<ostream&ます。(演算子のオーバーロードは、より近い一致が存在しない場合、サブクラスで使用できます。)これらのoperator<<オーバーロードはすべて。を返しostream&ます。

あなたができることは、関数にostream&とをとらせるdynamic_cast<>ことstringstream&です。間違ったタイプが渡された場合、bad_castがスローされます。

void printStringStream(ostream& os) {
    stringstream &ss = dynamic_cast<stringstream&>(os);
    cout << ss.str();
}

注:static_cast<>使用できます。高速になりますが、ではないものを渡した場合のバグプルーフにはなりませんstringstream

于 2012-09-20T19:54:49.120 に答える
2

があることがわかっているのでstringstream、戻り値をキャストするだけです。

stringstream var;
printStringStream(static_cast<stringstream&>(var << whatever));
于 2012-09-20T20:04:23.650 に答える
0

ミックスに追加するだけです。個人的には、破棄時に呼び出す必要のある関数を呼び出すストリームを作成します。

#include <sstream>
#include <iostream>

void someFunction(std::string const& value)
{
    std::cout << "someFunction(" << value << ")\n";
}

void method(std::string const& value)
{
    std::cout << "method(" << value << ")\n";
}

class FunctionStream
    : private virtual std::stringbuf
    , public std::ostream
{
public:
    FunctionStream()
        : std::ostream(this)
        , d_function(&method)
    {
    }
    FunctionStream(void (*function)(std::string const&))
    : std::ostream(this)
    , d_function(function)
    {
    }
    ~FunctionStream()
    {
        this->d_function(this->str());
    }
private:
    void (*d_function)(std::string const&);
};

int main(int ac, char* av[])
{
    FunctionStream() << "Hello, world: " << ac;
    FunctionStream(&someFunction) << "Goodbye, world: " << ac;
}

一時オブジェクトに送信される最初のオブジェクトは、特定のタイプのセット、つまりクラスstd::ostreamが知っているタイプのセットである必要があることに注意してください。通常、シフト演算子はstd::ostream&最初の引数として取りますが、一時オブジェクトをこれにバインドすることはできません。タイプ。ただし、メンバーであるため、参照にバインドする必要のないメンバー演算子がいくつかあります。最初にユーザー定義型を使用する場合は、メンバー入力演算子の1つを使用して実行できる一時的な参照を抽出する必要があります。

于 2012-09-20T23:05:39.753 に答える