私は、オペレータに< <のstd ::演算子をオーバーロードするときENDLが未知のタイプのものであり、<<
template <Typename T>
UIStream& operator<<(const T);
UIStream my_stream;
my_stream << 10 << " heads";
作品が、オーバーロードmy_stream << endl
を動作させるための回避策はありますか?
私は、オペレータに< <のstd ::演算子をオーバーロードするときENDLが未知のタイプのものであり、<<
template <Typename T>
UIStream& operator<<(const T);
UIStream my_stream;
my_stream << 10 << " heads";
作品が、オーバーロードmy_stream << endl
を動作させるための回避策はありますか?
std::endl
は関数であり、std::cout
はoperator<<
を実装して、std::endl
と同じシグネチャを持つ関数ポインタを取ることでそれを利用します。
そこに関数を呼び出し、戻り値を転送します。ここで
は、コード例です:
#include <iostream>
struct MyStream
{
template <typename T>
MyStream& operator<<(const T& x)
{
std::cout << x;
return *this;
}
// function that takes a custom stream, and returns it
typedef MyStream& (*MyStreamManipulator)(MyStream&);
// take in a function with the custom signature
MyStream& operator<<(MyStreamManipulator manip)
{
// call the function, and return it's value
return manip(*this);
}
// define the custom endl for this stream.
// note how it matches the `MyStreamManipulator`
// function signature
static MyStream& endl(MyStream& stream)
{
// print a new line
std::cout << std::endl;
// do other stuff with the stream
// std::cout, for example, will flush the stream
stream << "Called MyStream::endl!" << std::endl;
return stream;
}
// this is the type of std::cout
typedef std::basic_ostream<char, std::char_traits<char> > CoutType;
// this is the function signature of std::endl
typedef CoutType& (*StandardEndLine)(CoutType&);
// define an operator<< to take in std::endl
MyStream& operator<<(StandardEndLine manip)
{
// call the function, but we cannot return it's value
manip(std::cout);
return *this;
}
};
int main(void)
{
MyStream stream;
stream << 10 << " faces.";
stream << MyStream::endl;
stream << std::endl;
return 0;
}
うまくいけば、これはあなたにこれらのものがどのように動作するかのより良いアイデアを提供します。
私は私の答えを改善することができますので、あなたがダウンしたときにコメントを残してください。 – GManNickG
私はdownvoteをしませんでしたが、ここでは欠落している重要な情報があります:std :: endlは関数ではなくテンプレート関数です。これは、演算子<< overload as: 'template
ありがとう!これは別の質問に答えるのを助けました。 http://stackoverflow.com/questions/2196155 –
IOStreamsを拡張するためのより良い方法については、hereを参照してください。 (ちょっと古い、VC 6に合わせて作られているので、塩の穀粒でそれを取らなければならない)
ポイントは、ファンクターを動作させるためのもので、endl、どちらも "\ n"とフラッシュを出力するfunctor)では、完全なostreamインタフェースを実装する必要があります。
std
ストリームは、仮想メソッドがないのでサブクラス化されないように設計されているので、あまりにも遠すぎるとは思わないでしょう。あなたは、作業を行うためにstd :: ostreamを集約することができます。
あなたはそのようなendl
としてマニピュレータが
UStream& operator<<(UStream&, UStream& (*f)(UStream&));
または
UStream& UStream::operator<<(UStream& (*f)(UStream&));
すなわち、どのように処理されるかであるとして関数へのポインタを取る
operator<<
のバージョンを実装する必要が
endl
作業を行うには
今すぐstd::endl
はstd :: basic_ostreamへの参照を受け取って返す関数です。ストリームで直接動作しないように、あなた自身のバージョンを作る必要があります。 e std::endl
バージョンを集計しましたstd::iostream
。
編集:Looks likes GManの答えが良いです。彼はstd::endl
も働きます!
問題は、std::endl
が関数テンプレートで、演算子として<<
であることです。だから、あなたが書くとき:
my_stream << endl;
あなたはオペレータ のためだけでなく、endl
ためのテンプレートパラメータを推定するようにコンパイラを気に入るだろう。これは不可能です。
したがって、マニピュレータで作業する<<
〜 の追加の非テンプレートオーバーロードを記述する必要があります。彼らのプロトタイプは次のようになります。
UIStream& operator<<(UIStream& os, std::ostream& (*pf)(std::ostream&));
(2つの他の人はあなたがすべての マニピュレータを許可したい場合は、あなたが提供することも必要がありstd::basic_ios<char>
によってstd::ostream
と std::ios_base
を、交換がある)、その実装はと非常に似ていますあなたのテンプレート のいずれか。実際には、あなたがこのような 実装のためのテンプレートを使用することができるように似て:
typedef std::ostream& (*ostream_manipulator)(std::ostream&);
UIStream& operator<<(UIStream& os, ostream_manipulator pf)
{
return operator<< <ostream_manipulator> (os, pf);
}
最後の注意、多くの場合、カスタムstreambuf
を書くことは、多くの場合、1はテクニックにあなたを適用達成しようとするものを達成 に良い方法です使っている。
+1これは私が昨日提供したのと同じ回答です。不運にも無視されています。 http://stackoverflow.com/questions/1133739/how-does-ofstream-or-ostream-type-cast-all-types-to-string/1134501#1134501 –
実際に私は同じ解決策を見つけましたが、関数本体: 'pf(* this); return * this; '、しかし、私は' op << 'を、派生したostreamerクラスのメンバーとして追加します。 – TrueY
私はここに、私の問題を解決するためにこれをしなかったが、私のコードの一部です:
template<typename T>
CFileLogger &operator <<(const T value)
{
(*this).logFile << value;
return *this;
}
CFileLogger &operator <<(std::ostream& (*os)(std::ostream&))
{
(*this).logFile << os;
return *this;
}
MAIN.CPP
int main(){
CFileLogger log();
log << "[WARNINGS] " << 10 << std::endl;
log << "[ERRORS] " << 2 << std::endl;
...
}
私はここhttp://www.cplusplus.com/forum/general/49590/
ホープの参照を得ましたこれは誰かを助けることができます。 C++ 11と
受け入れ答えに加えて、タイプのoperator<<
をオーバーロードすることが可能である:
decltype(std::endl<char, std::char_traits<char>>)
UIStreamについては何も知らず、それは少しはコメントすることは困難です。 –
しかし、あなたは道を見つけました。 :) – notJim