C++03: 式 のMimeLogger() << "Hello "
場合、テンプレート関数
template <typename charT, class traits>
std::basic_ostream<charT, traits>& std::operator<< (
std::basic_ostream<charT, traits>& os,
const char* cstr);
一時MimeLogger()
は非 const 参照にバインドされない可能性があるため、オーバーロードの解決中には考慮されません。メンバー関数のオーバーロードにはこの問題はありません。これは、暗黙的なパラメーターの規則により、一時的なパラメーターへのバインドが許可されているためです。
C++11 右辺値参照をサポートするコンパイラを使用できる場合、これは意図したとおりに動作するはずです。これは、C++11 ライブラリが追加のオーバーロードを提供するためです。
template <typename charT, class traits, typename T>
std::basic_ostream<charT, traits>& std::operator<< (
std::basic_ostream<charT, traits>&& os,
const T& x ); // { os << x; return os; }
これにより、一時的なストリームが一時的<<
ではないかのように使用できます。
(g++ でテスト プログラムを試してみたところ、-std=c++0x を使用しない場合と使用した場合で異なる結果が得られました。)
C++11 に適したコンパイラを使用できない場合は、これを の public セクションに追加するclass MimeLogger
と、C++03 で必要なことができる回避策になります。
template<typename T>
MimeLogger& operator<<(const T& x)
{
static_cast<std::ostringstream&>(*this) << x;
return *this;
}
using std::ostringstream::operator<<;
using 宣言により、標準ライブラリのメンバー オーバーロードが からも確実に見えるようになりMimeLogger
ます。特に、これがないとマニピュレーターstd::endl
はテンプレート演算子を使用できません。これは、std::endl
それ自体が関数テンプレートであり、C++ から期待するにはあまりにも多くのテンプレート型推論であるためです。しかし、関数マニピュレーターを機能させるメンバーを非表示にしないことが確実である限り、問題はありませんostream
(27.7.3.6.3):
namespace std {
template <typename charT, class traits>
class basic_ostream : /*...*/ {
public:
basic_ostream<charT, traits>& operator<<(
basic_ostream<charT,traits>& (*pf)(basic_ostream<charT,traits>&));
};
}