次の最小限の例を考えてみましょう。
#include <iostream>
using namespace std;
class myostream : public ostream {
public:
myostream(ostream const &other) :
ostream(other.rdbuf())
{ }
};
int main() {
cout << "hello world" << endl;
myostream s(cout);
s << "hello world" << endl;
myostream(cout) << "hello world" << endl;
}
g++とVisualC++の両方での出力は次のとおりです。
hello world
hello world
0x4012a4
一時オブジェクトに書き込むバージョンは、free演算子ではなくmyostream(cout)
、member演算子を優先するように見えます。オブジェクトに名前があるかどうかに違いがあるようです。ostream::operator<<(void *)
operator<<(ostream &, char *)
なぜこれが起こるのですか?そして、どうすればこの動作を防ぐことができますか?
編集:なぜそれが起こるのかは、さまざまな答えから明らかになりました。これを防ぐ方法については、次のことが魅力的です。
class myostream : public ostream {
public:
// ...
myostream &operator<<(char const *str) {
std::operator<<(*this, str);
return *this;
}
};
ただし、これにより、あらゆる種類のあいまいさが生じます。