私は自分のログクラスを改造しようとしています。しかし、私は問題に直面しています。
私はユーザーに、このインターフェイスを公開する:決定的な破壊に頼って、復帰時の破壊を避ける
mylog() << "hello";
アイデアはmylog
が定義されたログタイプのためにいくつかの有用な特性を定義するLogger
のインスタンスであることです。そのoperator()
関数は、タイプLogStream
のインスタンスを返します。しかし、最後に改行文字を自動的に出力したいので、LogStream
のデストラクタでそれを行う考えがありました。
私の現在の実装では、この(LogStream
とLogger
が大幅にダウン易しく書き直されている)のようになります。Interstingly
#include <iostream>
struct LogStream
{
~LogStream() { std::cout << '\n'; }
template<class T>
LogStream& operator<<(const T& t)
{
std::cout << t;
return *this;
}
};
struct Logger
{
LogStream operator()()
{
return LogStream{} << "message: ";
}
};
int main()
{
Logger log;
log() << "hello!";
}
、私は私の以前の実装は、RVOに依存したコードのこの作品を考え出しました。コンパイラは常にコピー・エリジョンを実行していたので、デストラクタは必要な方法で動作しました。ただし、このコードでは、コピーが発生したときにコピーコンストラクタが呼び出されているため、改行文字は2回出力されています(operator()
)。
問題は、私は一時的なインスタンスを返し、代わりにoperator()
の体でこれを入れないと消え:
LogStream stream;
stream << "message: ";
return stream;
今RVOが、それは私が望むように動作します。
私は後で= delete
コピーコンストラクタを作成しました。なぜなら、とにかくそれが意味を成し、効果的にコードをコンパイルできないからです。
RVOに依存するハッピーソリューションを使用せずに、私が望むインターフェイスを提供するためのオプションは何ですか?
デストラクタで改行を出力する必要があるかどうかを示すために 'LogStream'の中にフラグを追加し、移動したときにこのフラグをfalseに設定します。 – Holt
それはうまくいくでしょうし、おそらく最も簡単な解決策かもしれませんが、私はそれを好きではありません。私はむしろコピーコンストラクタを削除したままにしておきます。 – Asu
@Asu、Holtの提案を使用することができない場合は、RVOが "可能かもしれない"(コードスニペットのような特定のコンテキストで)ではないC++ 17標準でコンパイルする必要があるかもしれません。 – WhiZTiM