Skip to main content
GameDev.net gamedev.net
🔒 Locked

typeof() operator

Started by rKallmeyer Jun 9, 2005 at 4:09 PM 13 replies 2k views
Original Post
rKallmeyer
rKallmeyer
Guru programmers out there: Is there anything potentially wrong with the following code?

// Returns A Unique Integer for every Type
template <typename T>
inline Int64 typeof (const T& rT)
{
    static T data;
    return reinterpret_cast <Int64>((void*)&data);
}

Usage as follows:


...

    // These examples arn't very sensible, but they show how it could be used
    
    template <typename T1, typename T2>
    bool isSameType (const T1& rT1, const T2& rT2)
    {
        return (typeof (rT1) == typeof (rT2));
    }

    ....

    class Any
    {
    public:
        template <typename T>
        Any (const T& rT)
        {
             ....
        }

        template <typename T>
        T cast ()
        {
            assert (type_ = typeof (T()));
            return reinterpret_cast <T>(pData_);
        }

        ...

    private:
        void* pData_;
        Int64 type_; 
    }

...

Boku San
Boku San
Maybe you mean to use typeid()? (as opposed to typeof()?)

But don't quote me on that.
Things change.
DrEvil
DrEvil
Looks a little hacky to me.

Using the address of some static variable as the type identifier for a type. This is most certainly not valid outside of a single run of the process, meaning if you write that stuff out to file it's probably gonna be useless when reading back in.

Is this meant to be like home made RTTI ?
rKallmeyer
rKallmeyer
Quote:
Original post by DrEvil
Looks a little hacky to me.

Using the address of some static variable as the type identifier for a type. This is most certainly not valid outside of a single run of the process, meaning if you write that stuff out to file it's probably gonna be useless when reading back in.

Is this meant to be like home made RTTI ?


I suppose it is alittle like home made RTTI, just with very little overhead. I haven't thought of a problem that coundln't be solved in a more elegant way, but still it seems like a useful little function.

Using an offset I could fix the problem with process locality:

struct type_offset { static int offset; };// Returns A Unique Integer for every Typetemplate <typename T>inline Int64 typeof (const T& rT){    static T data;    return  reinterpret_cast <Int64>(&type_offset::offset) -             reinterpret_cast <Int64>((void*)&data);}


What do you think?
snk_kid
snk_kid
Quote:
Original post by Nuget5555
I suppose it is alittle like home made RTTI, just with very little overhead.


typeid is a constant time operation, the result of typeid (a constant reference to std::type_info) can be even obtained at compile-time. All types be it built-in or user-defined have an associated type_info where needed.

Quote:
Original post by Nuget5555
What do you think?


For type identification, honestly i think you're wasting time unless portable string names are important to you then std::type_info is not portable in this case, if its not it might be better to build off of it instead if its to primitive for you.
rKallmeyer
rKallmeyer
Quote:
Original post by snk_kid
Quote:
Original post by Nuget5555
I suppose it is alittle like home made RTTI, just with very little overhead.


typeid is a constant time operation, the result of typeid (a constant reference to std::type_info) can be even obtained at compile-time. All types be it built-in or user-defined have an associated type_info where needed.

Quote:
Original post by Nuget5555
What do you think?


For type identification, honestly i think you're wasting time unless portable string names are important to you then std::type_info is not portable in this case, if its not it might be better to build off of it instead if its to primitive for you.


I did not realize how convenient typeid () is. Thanks for the heads up.
DrEvil
DrEvil
Yea looks like you're implementing your own version of what the typeid operator does, without the .name() option. It still doesn't replace dynamic_cast, as it has no concept of parent classes for down casting pointers and such.
mgarriss
mgarriss
someone should try using this to give boost::any an operator==, something i would love to have.
rKallmeyer
rKallmeyer
It looks like the ability to store the type of a variable has been purposefully removed from typeid (). Why?

Quote:
Original post by mgarriss
someone should try using this to give boost::any an operator==, something i would love to have.


That was part of the original idea.
snk_kid
snk_kid
Quote:
Original post by mgarriss
someone should try using this to give boost::any an operator==, something i would love to have.


You can simply do that yourself if really want to:

#include <boost/any.hpp>#include <boost/any.hpp>#include <typeinfo>bool operator==(const boost::any& lhs, const boost::any& rhs) {	return lhs.type() == rhs.type();}bool operator==(const boost::any& lhs, const std::type_info& rhs) {	return lhs.type() == rhs;}bool operator==(const std::type_info& lhs, const boost::any& rhs) {	return rhs == lhs;}


unless i'm missing something, boost::any::type returns a constant reference to std::type_info so its obviously using typeid.
JohnBolton
JohnBolton
There is one potential problem. Recently, the default linkage for inline functions was changed from local to external. That means that with older or non-compliant compilers and linkers, there may be several instances of the static variable 'data'. You could use "external inline" just to make sure.
John BoltonLocomotive Games (THQ)Current Project: Destroy All Humans (Wii). IN STORES NOW!
mgarriss
mgarriss
close but you'll also have to compare the values, not just the types.
rKallmeyer
rKallmeyer
Quote:
Original post by Nuget5555
It looks like the ability to store the type of a variable has been purposefully removed from typeid (). Why?


Oops, silly mistake. I was trying to store the std::type_info itself rather then a reference to it. My original idea is trumped by the beauty of typeid (). Thanks for all your help.

mgarriss
mgarriss
the other problem with a boost::any operator== is that how do you cast the any to use the correct operator== of the actaul type. you can't cast with type_info. you could compare the actual bytes but that would not work in cases where the object has refs and pointers or some odd def of operator==.

_ugly
snk_kid
snk_kid
Quote:
Original post by mgarriss
close but you'll also have to compare the values, not just the types.


okay i thought you where referring to comparing types only. Then yes you would have to take it further some how.

Topic Locked

This topic has been locked by a moderator. New replies are not allowed.

Sign in to reply to this topic.