Sign in to follow this  
rKallmeyer

typeof() operator

Recommended Posts

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

...

Share this post


Link to post
Share on other sites
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 ?

Share this post


Link to post
Share on other sites
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 Type
template <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?

Share this post


Link to post
Share on other sites
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.

Share this post


Link to post
Share on other sites
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.

Share this post


Link to post
Share on other sites
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.

Share this post


Link to post
Share on other sites
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.

Share this post


Link to post
Share on other sites
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.

Share this post


Link to post
Share on other sites
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.

Share this post


Link to post
Share on other sites
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.

Share this post


Link to post
Share on other sites
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

Share this post


Link to post
Share on other sites
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.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this