4

<< 演算子 (operator<<) を文字列を直接操作するように定義することは、ostringstreams を操作してから文字列に戻すよりも洗練されているように思えます。C ++がそのままではこれを行わない理由はありますか?

#include <string>
#include <sstream>
#include <iostream>
using namespace std;

template <class T> 
string& operator<<(string& s, T a) {
    ostringstream ss;
    ss << a;
    s.append(ss.str());
    return s;
}
int main() {
    string s;
    // this prints out: "inserting text and a number(1)"
    cout << (s << "inserting text and a number (" << 1 << ")\n");

    // normal way
    ostringstream os; 
    os << "inserting text and a number(" << 1 << ")\n";
    cout << os.str();
}
4

3 に答える 3

3

ストリームには追加の状態が含まれます。これが可能かどうか想像してみてください。

std::string str;
int n = 1234;
str << std::hex;
str << n;
return str; // returns "0x4d2" (or something, I forget)

この追加の状態を維持するには、文字列にこの状態のストレージが必要です。C ++標準委員会(および一般的なC ++プログラマー)は、「使用した分だけ支払う」というモットーの下で、一般的に過剰なリソースの消費に眉をひそめています。したがって、文字列クラスに余分なフィールドはありません。

主観的な答え:std::string特にC ++の優れた標準ライブラリの他の部分と比較して、クラスは最初から非常に貧弱に設計されていると思います。機能を追加std::stringすると、事態はさらに悪化します。これは非常に主観的な意見であり、私を熱狂的な狂人として自由に却下してください。

于 2013-02-10T07:09:41.920 に答える
2

文字列を出力ストリームにするという考え方の問題は、文字列が重くなりすぎることです。

文字列は、出力をフォーマットするためではなく、「文字列データを保持する」ことを目的としています。出力ストリームには、操作可能な重い「状態」があり (「参考文献」を参照<iomanip>)、保存する必要があります。これはもちろん、すべてのプログラムのすべての文字列に対してこれを保存する必要があることを意味しますが、出力ストリームとして使用されるものはほとんどありません。したがって、リソースの大幅な浪費です。

C++ は、「ゼロ オーバーヘッド」の設計原則に従います (または、少なくとも必要以上のオーバーヘッドはありません)。不必要なオーバーヘッドを追加しない文字列クラスを持たないことは、この設計原則に大きく違反することになります。これが事実である場合: オーバーヘッドが重大なケースでは、人々は何をしますか? C ストリングを使用してください。

C++11 では、別の方法としてoperator+=withを使用して文字列に追加し、出力ストリームの のstd::to_stringようにチェーンすることもできます。必要に応じて、 と の両方を素敵な文字列でoperator<<ラップできます。+=to_stringoperator<<

template <class Number> 
std::string& operator<<(std::string& s, Number a) {
    return s += std::to_string(a);
}
std::string& operator<<(std::string& s, const char* a) {
    return s += a;
}
std::string& operator<<(std::string& s, const std::string &a) {
    return s += a;
}

この方法を使用して更新された例: http://ideone.com/4zbVtD

于 2013-02-10T07:13:37.347 に答える
0

おそらく時間の経過とともに失われましたが、フォーマットされた出力は常にC のストリームに関連付けられており (「実際の」文字列を持たないため)、これは C++ に引き継がれた可能性があります (結局のところ、C はクラス付きでした)。 . C では、文字列にフォーマットする方法は、output-to-stream 関数のsprintfバリエーションであるを使用することです。fprintf

明らかに私の側の推測ですが、ストリーム内のこれらの書式設定は文字列にもあると素晴らしいと誰かがおそらくあなたと同じように考えたので、ストリームクラスをサブクラス化して、文字列を「出力」として使用するクラスを生成しました。

これは、できるだけ早く機能させるためのエレガントなソリューションのようです。そうしないと、ストリームと文字列で書式設定コードが重複していたでしょう。

于 2013-02-10T07:05:49.820 に答える