是否有可能使用类型擦除来创建封装任意类型(称为ErasedType
)的对象,并可以在运行时查询以确定另一个任意类型T
是否可转换为ErasedType
?
经过思考,我认为这不可能-即使理论上似乎有可能。编译器会知道我们正在尝试与ErasedType
进行比较的哪些类型T
,因此可以在运行之前生成必要的代码。问题在于,在实践中,似乎没有任何方法将模板参数类型从基类实例传递到子类实例。
例如:
struct FooBase
{
template <class TestType>
bool is_convertible()
{
return call_derived();
}
protected:
virtual bool call_derived() = 0;
template <class ErasedType>
void base_class_function() { }
};
template <class ErasedType>
struct Foo : public FooBase
{
bool call_derived()
{
// Here we have access to the ErasedType but no access to TestType.
//
// We could pass ErasedType to a base class function by saying:
//
// this->base_class_function<ErasedType>();
//
// ...but that doesn't seem to help since we still don't have access to
// TestType
}
};
所以,目标是能够说出类似这样的话:
FooBase* f = new Foo<int>();
bool res1 = f->is_convertible<double>(); // returns true
bool res2 = f->is_convertible<long>(); // returns true
bool res3 = f->is_convertible<std::string>(); // returns false
但是,我看不出如何实现FooBase::is_convertible
方法,因为我看不到在同一个函数中使TestType
和ErasedType
可访问的方法,以便编译器可以计算std::is_convertible<TestType, ErasedType>::value
的结果。
那么,这是否有可能呢?
type_id
……但是特征是编译时构造,不会真正与动态类型交互。 - Kerrek SBTestType
和ErasedType
都不被隐藏的情况呢? - Channel72