George Kourtis
George Kourtis

Reputation: 2592

Using RTTI with plain old structures (gcc)

I need to "attach" to an external ( non modifiable ) struct some sort of RTTI information.

As I have seen from the gcc implementation, struct's with virtual methods have additionally at their beginning a pointer to a struct related to the type_info.

So my need would be to operate on those external structures by using a double pointer that has both parts: the data pointer and the "type" pointer. That double pointer has all the information of a "normal" RTTI structure. Do you know of any "legal" or hacky way to do it

Upvotes: 0

Views: 449

Answers (1)

milleniumbug
milleniumbug

Reputation: 15824

Create a smart pointer class for that:

#include <typeindex>
#include <type_traits>

// minimal implementation
template<typename T>
class RTTIPointer
{
    T* ptr_;
    std::type_index type_;
public:
    template<typename U, typename std::enable_if<std::is_convertible<U*, T*>::value>::type* = nullptr>
    RTTIPointer(U* p) :
        ptr_(p),
        type_(typeid(*p))
    {

    }

    // typename std::add_lvalue_reference<T>::type instead of T&
    // to support void pointers
    typename std::add_lvalue_reference<T>::type operator*() const
    {
        return *ptr_;
    }

    T* operator->() const
    {
        return ptr_;
    }

    T* get() const
    {
        return ptr_;
    }

    std::type_index type() const
    {
        return type_;
    }
};

struct Base { int a; };
struct Derived : Base { int b; };

#include <iostream>

int main()
{
    Derived b;
    b.a = 2;
    b.b = 3;
    RTTIPointer<Base> r(&b);
    std::cout << r->a << "\n" << r.type().name() << "\n";
    RTTIPointer<void> q(&b);
    std::cout << r.type().name() << "\n";
}

Output:

2
7Derived
7Derived

Upvotes: 2

Related Questions