使用Type-Erasure创建运行时type_traits查询

Cha*_*l72 5 c++ templates type-erasure

是否可以使用Type Erasure创建封装任意类型的对象(让我们称之为ErasedType),并且可以在运行时查询以判断另一个任意类型是否T可以转换为ErasedType

考虑这件事后,我不认为这是可能的-尽管现在看来,这可能潜在有可能在理论上.编译器会知道T我们要与哪些类型进行比较ErasedType,因此可以在运行时生成必要的代码.问题是,在实践中,似乎没有任何方法可以将模板参数类型从Base类实例传递给Subclass实例.

例如:

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
    }
};
Run Code Online (Sandbox Code Playgroud)



所以,目标是能够说出类似的话:

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
Run Code Online (Sandbox Code Playgroud)

但是,我看不出该FooBase::is_convertible方法是如何实现的,因为我看不到在同一个函数中一起制作TestTypeErasedType访问,所以编译器可以计算结果std::is_convertible<TestType, ErasedType>::value

那么,这有可能吗?

GMa*_*ckG 2

一般来说,这在 C++ 中确实是不可能的。在运行时对类型进行任意查询需要相当多的元数据,而 C++ 试图将其保持在最低限度(有时有点烦人;某个功能可以在“使用时”自动选择加入,因此没有不必要的开销,但我离题了)。

正如 David 所提到的,在一定程度上复制编译器信息是完全有可能的,但永远不会完全自动。这将运行时类型信息限制为您手动添加的内容。

看一下像Qt这样的库,它们在 C++ 之上有一个完整的框架来提供元数据,看看涉及什么类型的工作。根据当前的问题,您也许可以在没有它的情况下完成。