Rubyのようないくつかの言語では、フォーマットされた出力 を「ワンライナー」として作成するための派手な構文があります。`std :: ostringstream`が` std :: ostringstream& `を返す` operator << `を持っていたらどうなりますか?
これは、一部のC++アプリケーションでも一般的に必要です。
:彼らはこのような何かを書くことができるようにするためstruct string_formatter {
std::ostringstream ss;
template <typename T>
string_formatter & operator << (const T & t) {
ss << t;
return *this;
}
operator std::string() const {
return ss.str();
}
};
:ここではいくつかのサンプルコードです:
if (num_doggies > num_biscuits) {
std::ostringstream ss;
ss << "There are " << num_doggies" << " puppy dogs and only " << num_biscuits << " biscuits!";
log_warn(ss.str());
this->negotiate_biscuit_reduction();
}
いくつかのオープンソースC++ 98件のプロジェクトは、このようになります回避策を持っています
if (num_doggies > num_biscuits) {
log_warn(string_formatter{} << "There are " << num_doggies" << " puppy dogs and only " << num_biscuits << " biscuits!");
this->negotiate_biscuit_reduction();
}
3行を1行に変換します。
しかし、string_formatter
クラスは、この暗黙の変換の主な理由で、コードレビューの観点からかなり悪いです。 暗黙のコンバージョンは通常 と思われ、共通タイプまたはプリミティブタイプに変換するときにはより悪いです int
またはstd::string
のようになります。 C++ 11では
我々はわずかに変更することができ:string_formatter
はR値の基準である場合
operator std::string() && {
return ss.str();
}
今変換のみトリガされます。 したがって、トリガーする可能性は低くなりますが、さらに複雑になります。それは実際に悪くないですか? 議論の余地があります。
も言及する価値:他の人はこれがstring_formatter
シムなし を動作させるためにさらにより精巧なハック行っている:ここhttps://codereview.stackexchange.com/questions/6094/a-version-of-operator-that-returns-ostringstream-instead-of-ostream
ません暗黙の型変換を、私たちは通常、標準ライブラリのタイプに演算子をオーバーロードしていますいいえ。
少しバックアップしましょう。なぜ私は妥協してこれを行うことができないのですか?それは、少なくとも、もう少しコンパクトだ:
if (num_doggies > num_biscuits) {
std::ostringstream ss;
log_warn((ss << "There are " << num_doggies" << " puppy dogs and only " << num_biscuits << " biscuits!").str());
this->negotiate_biscuit_reduction();
}
ためstd::ostringstream::operator <<
戻りstd::ostream &
なく std::ostringstream &
それは、これはコンパイルできないことが判明します。 <<
が解決されるまでには、を使用できないため、ostream &
しかありません。
私の質問は、なぜその場合ですか?
なぜですかstd::ostringstream::operator <<
返信std::ostringstream &
?それは次のとおりです。技術的または安全上の理由から
- 望ましくない
- は
- レガシー標準ライブラリの実装者のための不必要な難易度を追加する - それは、常にこの方法だったと、今、それを変更するコードを壊すかもしれません。 (しかし、正確にどのようなコードがこれによって壊れてしまうのでしょうか?
std::ostringstream &
は継承関係のために標準変換によってstd::ostream &
に変換される可能性があります)。 - あくまでも参考にしてください。
注:私はstring_formatter
とロガークラスを設計するさまざまな方法をよく知っています。私は具体的には、std::ostringstream
がstd::ostream &
を返すほうがずっと良い標準ライブラリに設計上の理由があるかどうかに関心があります。
あなたは自明なし、string_formatter' 'に'の.strを() '追加することができますか? –
@ T.C。うん、それは本当にポイントではない、なぜ私はなぜ 'std :: ostringstream'が' std :: ostream& 'を返す必要があるのか分からない理由があるなら、もっと興味があります –
ostringstreamに演算子がないので?それは、基本的なostream oneを継承の魔法によって使います。 –