Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using Type-Erasure to create runtime type_traits queries

Is it at all possible to use Type Erasure to create objects that encapsulate an arbitrary type, (let's call it ErasedType), and can be queried at runtime to tell whether another arbitrary type T is convertible to ErasedType?

After thinking about it, I don't think it's possible - even though it seems it could potentially be possible in theory. The compiler would know which types T we're trying to compare with ErasedType, and so could generate the necessary code before runtime. The problem is that, in practice, there doesn't seem to be ANY way to pass a template parameter type from a Base class instance to a Subclass instance.

For example:

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
    }
};



So, the goal is to be able to say something like:

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

But, I can't see how the FooBase::is_convertible method could ever be implemented, since I see no way to make TestType and ErasedType accessible together, in the same function, so the compiler could compute the result of std::is_convertible<TestType, ErasedType>::value

So, is this at all possible?

like image 274
Channel72 Avatar asked Nov 03 '22 18:11

Channel72


1 Answers

It is indeed not possible in C++, in general. It takes quite a bit of meta-data to make arbitrary queries about types at runtime, and C++ tries to keep this minimal (sometimes to the point of being a bit annoying; a feature could be automatically opt-in "on use", so there's no unnecessary overhead, but I disgress).

As David has been alluding to, it's entirely possible to duplicate the compilers information up to a point, but never fully automatically. This limits the runtime type information to what you manually add.

Take a look at libraries like Qt that have an entire framework on top of C++ to provide this meta-data to see what kind of work is involved. Depending on the problem at hand, you may be able to get by without it.

like image 114
GManNickG Avatar answered Nov 08 '22 09:11

GManNickG