ヒープ割り当てオブジェクトのラッパーとして機能するクラスを作成しているときに、この単純な例に要約できる暗黙的な型変換の問題に遭遇しました。
以下のコードでは、ラッパー クラスがヒープ割り当てオブジェクトを管理し、暗黙的にそのオブジェクトへの参照に変換します。これにより、暗黙的な変換が行われるため、ラッパー オブジェクトを引数として関数 write(...) に渡すことができます。
ただし、明示的なキャストが行われない限り、operator<<(...) の呼び出しを解決しようとすると、コンパイラは失敗します (MSVC8.0、Intel 9.1、および gcc 4.2.1 コンパイラで確認)。
では、(1) この場合、暗黙的な変換が失敗するのはなぜですか? (2)引数依存のルックアップに関連している可能性がありますか?(3)明示的なキャストなしでこれを機能させるためにできることはありますか?
#include <fstream>
template <typename T>
class wrapper
{
T* t;
public:
explicit wrapper(T * const p) : t(p) { }
~wrapper() { delete t; }
operator T & () const { return *t; }
};
void write(std::ostream& os)
{
os << "(1) Hello, world!\n";
}
int main()
{
wrapper<std::ostream> file(new std::ofstream("test.txt"));
write(file);
static_cast<std::ostream&>( file ) << "(2) Hello, world!\n";
// file << "(3) This line doesn't compile!\n";
}