При написании класса, который действует как оболочка для объекта, выделенного в куче, я столкнулся с проблемой неявного преобразования типа, которую можно свести к этому простому примеру.
В приведенном ниже коде класс-оболочка управляет объектом, выделенным в куче, и неявно преобразуется в ссылку на этот объект. Это позволяет передавать объект-оболочку в качестве аргумента функции write (...), поскольку имеет место неявное преобразование.
Однако компилятор терпит неудачу при попытке разрешить вызов оператора ‹< (...), если не сделано явное приведение (проверено с компиляторами 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";
}