C++ストリームとしてのパラメータが過負荷オペレーター<<
-
25-09-2019 - |
質問
ようにしている自分でログインのクラスとして使用してストリーム:
logger L;
L << "whatever" << std::endl;
このコードを始めた。
#include <iostream>
using namespace std;
class logger{
public:
template <typename T>
friend logger& operator <<(logger& log, const T& value);
};
template <typename T>
logger& operator <<(logger& log, T const & value) {
// Here I'd output the values to a file and stdout, etc.
cout << value;
return log;
}
int main(int argc, char *argv[])
{
logger L;
L << "hello" << '\n' ; // This works
L << "bye" << "alo" << endl; // This doesn't work
return 0;
}
たがってエラーにしようとした場合にコンパイルといった定義のためのオペレーター<< 大阪大学未来戦略機構(std::ァイル):
pruebaLog.cpp:31: error: no match for ‘operator<<’ in ‘operator<< [with T = char [4]](((logger&)((logger*)operator<< [with T = char [4]](((logger&)(& L)), ((const char (&)[4])"bye")))), ((const char (&)[4])"alo")) << std::endl’
っている過負荷のオペレーター<< このような流れで走っmad.わからないことを思い出します。ってlokingで、インスタンスの定義std::ァイルをostreamヘッダファイルは、筆記機能はこのヘッダ:
logger& operator <<(logger& log, const basic_ostream<char,char_traits<char> >& (*s)(basic_ostream<char,char_traits<char> >&))
ができます。また、同じテンプレートを使用する代わりに直接使用char、もしを使っているだけで"const ostream&os"、と。
このバグだと思い、エラー出力には、最初の引数のためのオペレーター<< 変化のもとへの参照ポインタものように見えるダブル参照...
解決
endl
は奇妙な獣です。これは、一定の値ではありません。それは、すべてのものの、実際には機能です。あなたはendl
のアプリケーションを処理するための特別なオーバーライドを必要があります。
logger& operator<< (logger& log, ostream& (*pf) (ostream&))
{
cout << pf;
return log;
}
これはostream
参照を受け取り、ostream
リファレンスを返す関数の挿入を受け付けます。何endl
のであること。
の編集の「なぜ、自動的にこのコンパイラを推論できないのですか?」のFranticPedanticの興味深い質問に対して。その理由は、あなたがまだ深く掘り下げた場合、endl
は実際にのテンプレートの機能そのものであるということです。それは次のように定義されています:
template <class charT, class traits>
basic_ostream<charT,traits>& endl ( basic_ostream<charT,traits>& os );
は、それがその入力と出力としてostream
の任意の並べ替えを取ることができます。問題は、関数ポインタ可能性があり、コンパイラはそのT const &
を推測することができないということではありませんが、それは、のどのお渡しすることを意図し、のendl
を把握することはできません。operator<<
のテンプレートバージョンを提示するように問題の2番目の引数として任意の関数へのポインタを受け入れるだろうが、コンパイラは意味のあるものそこを行うことはできませんので、同時に、endl
テンプレートは、潜在的な機能のの無限のセットを表します。
二番目の引数と一致するoperator<<
テンプレートのの特定ののインスタンス化が解決への呼び出しを可能にendl
の特別な過負荷を提供します。
他のヒント
endl
は、参照することによりストリームを受け入れるファンクタであるIOマニピュレータであり、その上にいくつかの操作を行い、リターンも参照することによりストリーム、すなわち。 cout << endl
はcout << '\n' << flush
は、出力バッファをフラッシュするマニピュレータでflush
、と等価である。
あなたのクラスでは、あなたはこの演算子のオーバーロードを記述する必要があります:
logger& operator<<(logger&(*function)(logger&)) {
return function(*this);
}
logger&(*)(logger&)
参照によりlogger
を受け入れ、返す関数の一種です。独自のマニピュレータを書き込むには、単に機能と一致するその署名を書き、それがストリーム上で、いくつかの操作を実行する必要があります:
logger& newline(logger& L) {
return L << '\n';
}
この問題はストリームのない過負荷 operator<<
受け入れる機能は同一型式として std::endl
このようにこの答え: std::ァイルが未知のタイプがオーバーロードオペレーター<<
C++では、 ストリームバッファ このカプセル化基礎I/O mechanisim.ストリーム自体のみでカプセル化の変換文字列のI/O。
このように使用に定義済みのストリームの授業ずに取り出すことができるようにします。また新しいターゲットさせたいI/Oに行くようなシステムログには、何をすべき作成はお客様ご自身 ストリームバッファ にならない" std::streambuf
).