【发布时间】:2009-02-19 22:53:15
【问题描述】:
在编写一个类以充当堆分配对象的包装器时,我遇到了隐式类型转换的问题,可以简化为这个简单的示例。
在下面的代码中,包装类管理一个堆分配的对象并隐式转换为对该对象的引用。这允许将包装对象作为参数传递给函数 write(...),因为发生了隐式转换。
但是,当尝试解析对 operator
那么,(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";
}
【问题讨论】:
-
我完全错过了包装器的价值:在堆栈上创建的 fstream 对象会自行清理。相反,您在堆上创建了一个 fstream 对象,然后使用包装器来保证它在与开始清理时完全相同的位置被清理。
-
在实际版本中,我使用 boost::shared_ptr
而不是 T* 以便共享实例,并为共享实例实现必要的语义。这个例子被大大简化了,不是很现实,但足以说明问题。 -
如果模板的参数是自动解析的,则转换集是有限的。所以在你的情况下,如果你有 template
void write(basic_ostream&);你会遇到同样的问题(除了 op
标签: c++ type-conversion operator-keyword implicit-conversion