I'm working on a project that requires dynamic_cast. I understand its quite slow and should generally be avoided, that said I see no other way. To that end I thought I could perhaps speed up dynamic_cast by caching the results. So I put together a small class that seems to work for the limited test scenarios I threw at it. None-the-less its on the borderline of kosher and was wondering what other people think.
class FastDynamicCast {
private:
typedef const std::type_info* Type;
typedef std::tuple<Type,Type,Type> InterfaceId; // actual object type, src interface, dest interface
typedef std::map<InterfaceId,int> Table;
Table table;
public:
template <typename TR, typename T> TR Cast (T* ptr) {
static_assert(std::is_pointer<TR>::value,"TR must be a pointer type.");
static const int flag = std::numeric_limits<int>::max();
InterfaceId id(&typeid(*ptr),&typeid(T*),&typeid(TR));
auto i = table.find(id);
if (i == table.end()) {
TR r = dynamic_cast<TR>(ptr);
if (r) {
unsigned char* t0 = reinterpret_cast<unsigned char*>(ptr);
unsigned char* t1 = reinterpret_cast<unsigned char*>(r);
int diff = static_cast<int>(t1 - t0);
table.insert(Table::value_type(id,diff));
}
else {
table.insert(Table::value_type(id,flag));
}
return r;
}
else if (i->second == flag) return nullptr;
else {
unsigned char* t = reinterpret_cast<unsigned char*>(ptr);
t += i->second;
return reinterpret_cast<TR>(t);
}
}
};
Despite the fact that the underlying implementation isn't specified in the standard, for a given object, src, and dest interface the pointer transformation needs to be the same... right? I mean you can't have objects magically changing around their structure at runtime. Anyways I just thought I'd throw it out here to see what people thought and/or critique it.