質問

ようにしている自分でログインのクラスとして使用してストリーム:

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 << endlcout << '\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).

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top