typeid operator

Discussion in 'C++' started by Marco Jez, Oct 27, 2004.

  1. Marco Jez

    Marco Jez Guest

    Hi everyone!

    I would like to use the reference returned by typeid as key in a std::map.
    Is it safe to assume that typeid(T) (where T is a type name) will always
    return the same reference to the same type_info structure for a given T? My
    map would look like this:

    typedef std::map<const std::type_info &, ......> Type_map;

    Cheers,
    Marco
    Marco Jez, Oct 27, 2004
    #1
    1. Advertising

  2. "Marco Jez" <> wrote in message
    news:FORfd.214470$...

    > I would like to use the reference returned by typeid as key in a std::map.
    > Is it safe to assume that typeid(T) (where T is a type name) will always
    > return the same reference to the same type_info structure for a given T?


    I don't see why you should be able to make that assumption.

    The type_info::before member is intended to be used for defining a
    comparison function that you can use for making map keys out of typeids. If
    you use it, two distinct type_info objects that represent the same type
    should be treated as equivalent keys.
    Andrew Koenig, Oct 27, 2004
    #2
    1. Advertising

  3. Marco Jez wrote:
    > I would like to use the reference returned by typeid as key in a std::map.
    > Is it safe to assume that typeid(T) (where T is a type name) will always
    > return the same reference to the same type_info structure for a given T? My
    > map would look like this:
    >
    > typedef std::map<const std::type_info &, ......> Type_map;


    Yes, that's guaranteed.

    V
    Victor Bazarov, Oct 27, 2004
    #3
  4. Andrew Koenig wrote:
    > "Marco Jez" <> wrote in message
    > news:FORfd.214470$...
    >
    >
    >>I would like to use the reference returned by typeid as key in a std::map.
    >>Is it safe to assume that typeid(T) (where T is a type name) will always
    >>return the same reference to the same type_info structure for a given T?

    >
    >
    > I don't see why you should be able to make that assumption.


    I think the Standard in 5.2.8 says that the lvalue is returned and that
    the lifetime of the object referred to by the lvalue is entire program.
    So, why should we be able to make that assumption? Or did you forget the
    'not' as in "I don't see why you should _not_ be able..."?

    The only doubt I have is that the OP's map is made to have the reference
    as the key type. Is it possible? "Key" is required to be assignable.
    Are references assignable? I kind of think they are fine, but are they?

    > The type_info::before member is intended to be used for defining a
    > comparison function that you can use for making map keys out of typeids. If
    > you use it, two distinct type_info objects that represent the same type
    > should be treated as equivalent keys.


    V
    Victor Bazarov, Oct 27, 2004
    #4
  5. "Victor Bazarov" <> wrote in message
    news:0LSfd.7263$09.us.to.verio.net...
    > Andrew Koenig wrote:
    > > "Marco Jez" <> wrote in message
    > > news:FORfd.214470$...
    > >
    > >
    > >>I would like to use the reference returned by typeid as key in a std::map.
    > >>Is it safe to assume that typeid(T) (where T is a type name) will always
    > >>return the same reference to the same type_info structure for a given T?

    > >
    > >
    > > I don't see why you should be able to make that assumption.

    >
    > I think the Standard in 5.2.8 says that the lvalue is returned and that
    > the lifetime of the object referred to by the lvalue is entire program.
    > So, why should we be able to make that assumption? Or did you forget the
    > 'not' as in "I don't see why you should _not_ be able..."?


    Wouldn't it be legal -- but insane -- for an implementation to have several
    type_info objects for a given type, each of which has lifetime equal to the
    entire program, and for typeid to to select one at random each time typeid is
    invoked?

    Perhaps support for dynamic libraries might sometimes lead to the existence of
    two typeid objects for the same type.

    Jonathan
    Jonathan Turkanis, Oct 27, 2004
    #5
  6. Marco Jez

    Marco Jez Guest

    "Andrew Koenig" <> ha scritto nel messaggio
    news:8uSfd.787921$...

    > I don't see why you should be able to make that assumption.


    That's why I've asked... :)
    Since it seemed to be true in my implementation I was wondering whether the
    Standard guarantees that or not. Anyway I didn't notice the before() member,
    my fault.

    > The type_info::before member is intended to be used for defining a
    > comparison function that you can use for making map keys out of typeids.
    > If you use it, two distinct type_info objects that represent the same type
    > should be treated as equivalent keys.


    So, would this map be guaranteed to work as expected?

    struct Type_info_cmp
    {
    bool operator()(const std::type_info *t1, const std::type_info *t2)
    const
    {
    return t1->before(*t2) != 0;
    }
    };

    typedef std::map<const std::type_info*, My_struct, Type_info_cmp>
    Type_map;

    Cheers,
    Marco
    Marco Jez, Oct 27, 2004
    #6
  7. Marco Jez

    Marco Jez Guest

    > The only doubt I have is that the OP's map is made to have the reference
    > as the key type. Is it possible? "Key" is required to be assignable.
    > Are references assignable? I kind of think they are fine, but are they?


    I was actually thinking of storing a pointer to the type_info structure, not
    a reference (I've corrected it in my reply to Andrew). Sorry for the
    confusion.

    Marco
    Marco Jez, Oct 27, 2004
    #7
  8. "Victor Bazarov" <> wrote in message
    news:0LSfd.7263$09.us.to.verio.net...
    > Andrew Koenig wrote:


    >>>I would like to use the reference returned by typeid as key in a
    >>>std::map. Is it safe to assume that typeid(T) (where T is a type name)
    >>>will always return the same reference to the same type_info structure for
    >>>a given T?


    >> I don't see why you should be able to make that assumption.


    > I think the Standard in 5.2.8 says that the lvalue is returned and that
    > the lifetime of the object referred to by the lvalue is entire program.
    > So, why should we be able to make that assumption? Or did you forget the
    > 'not' as in "I don't see why you should _not_ be able..."?


    Because I don't see any place in 5.2.8 that prohibits an implementation from
    having several distinct objects that represent a given type and returning a
    reference to one or another of those objects at whim.

    As a more realistic example, consider a class defined in a header file that
    is included in several translation units. Where does it say that the
    implementation can't create a separate type_info object in each translation
    unit?
    Andrew Koenig, Oct 27, 2004
    #8
  9. "Marco Jez" <> wrote in message
    news:DsTfd.214994$...
    > "Andrew Koenig" <> ha scritto nel messaggio


    >> The type_info::before member is intended to be used for defining a
    >> comparison function that you can use for making map keys out of typeids.
    >> If you use it, two distinct type_info objects that represent the same
    >> type should be treated as equivalent keys.


    > So, would this map be guaranteed to work as expected?
    >
    > struct Type_info_cmp
    > {
    > bool operator()(const std::type_info *t1, const std::type_info *t2)
    > const
    > {
    > return t1->before(*t2) != 0;
    > }
    > };
    >
    > typedef std::map<const std::type_info*, My_struct, Type_info_cmp>
    > Type_map;


    That's the idea.

    [The type_info::before member is in the standard because I proposed it, so I
    am confident in knowing its purpose :) ]
    Andrew Koenig, Oct 27, 2004
    #9
  10. Marco Jez wrote:
    > ...
    > I would like to use the reference returned by typeid as key in a std::map.
    > Is it safe to assume that typeid(T) (where T is a type name) will always
    > return the same reference to the same type_info structure for a given T? My
    > map would look like this:
    >
    > typedef std::map<const std::type_info &, ......> Type_map;
    > ...


    You cannot use any reference type as a key in an 'std::map' because
    reference types are not Assignable, which happens to be a requirement
    for 'std::map's key type. Use pointer to 'std::type_info' instead.

    Since the C++ standard doesn't explicitly guarantee that 'typeid' always
    return a reference to the same 'type_info' object for the same argument
    type, you'll have to supply the map with your own comparison predicate,
    which will perform "intellegent" comparison of 'type_info' pointers by
    comparing the pointed objects using 'std::type_info::before' method.

    --
    Best regards,
    Andrey Tarasevich
    Andrey Tarasevich, Oct 27, 2004
    #10
  11. Victor Bazarov wrote:
    > ...
    > The only doubt I have is that the OP's map is made to have the reference
    > as the key type. Is it possible? "Key" is required to be assignable.
    > Are references assignable? I kind of think they are fine, but are they?
    > ...


    They are not Assignable of course, by which I mean that any attempt to
    syntactically "assign" them will actually be applied to referenced objects.

    Firstly, that's definitely not what the OP wants. Secondly, it won't
    work because the referenced objects are const-qualified anyway. Thirdly,
    it won't work because 'std::type_info' objects are not Assignable
    themselves.

    --
    Best regards,
    Andrey Tarasevich
    Andrey Tarasevich, Oct 27, 2004
    #11
  12. Hi Marco,

    this is covered as well in the Loki Library. There is a class storing the
    pointer to a type_info and comparing via the before function.

    A short version looks like this:


    class CTypeInfo
    {
    public:
    CTypeInfo(const std::type_info& ti) : pInfo_(&ti) // non-explicit
    {
    assert(pInfo_);
    }
    // Access for the wrapped std::type_info
    const std::type_info& Get() const
    {
    assert(pInfo_);
    return *pInfo_;
    }
    // Compatibility functions
    bool before(const CTypeInfo & rhs) const
    {
    assert(pInfo_);
    return pInfo_->before(*rhs.pInfo_) != 0;
    }
    private:
    const std::type_info* pInfo_;
    };

    // Implementation
    inline bool operator<(const CTypeInfo& lhs, const CTypeInfo& rhs)
    {
    return lhs.before(rhs);
    }


    You can use this class directly in a map then.

    Regards,
    Patrick
    Patrick Kowalzick, Oct 27, 2004
    #12
  13. Patrick Kowalzick wrote:
    > class CTypeInfo
    > {
    > ...
    > // Compatibility functions
    > bool before(const CTypeInfo & rhs) const
    > {
    > assert(pInfo_);


    assert(pInfo_ && rhs.pInfo_)

    would better fit the general style of using assertions in this code.

    > return pInfo_->before(*rhs.pInfo_) != 0;
    > }
    > ...


    --
    Best regards,
    Andrey Tarasevich
    Andrey Tarasevich, Oct 27, 2004
    #13
  14. > would better fit the general style of using assertions in this code.
    >
    > > return pInfo_->before(*rhs.pInfo_) != 0;
    > > }


    true :)

    Thx,
    Patrick
    Patrick Kowalzick, Oct 27, 2004
    #14
  15. Marco Jez

    Tom Widmer Guest

    On Wed, 27 Oct 2004 13:55:18 -0600, "Jonathan Turkanis"
    <> wrote:

    >
    >"Victor Bazarov" <> wrote in message
    >news:0LSfd.7263$09.us.to.verio.net...
    >> Andrew Koenig wrote:
    >> > "Marco Jez" <> wrote in message
    >> > news:FORfd.214470$...
    >> >
    >> >
    >> >>I would like to use the reference returned by typeid as key in a std::map.
    >> >>Is it safe to assume that typeid(T) (where T is a type name) will always
    >> >>return the same reference to the same type_info structure for a given T?
    >> >
    >> >
    >> > I don't see why you should be able to make that assumption.

    >>
    >> I think the Standard in 5.2.8 says that the lvalue is returned and that
    >> the lifetime of the object referred to by the lvalue is entire program.
    >> So, why should we be able to make that assumption? Or did you forget the
    >> 'not' as in "I don't see why you should _not_ be able..."?

    >
    >Wouldn't it be legal -- but insane -- for an implementation to have several
    >type_info objects for a given type, each of which has lifetime equal to the
    >entire program, and for typeid to to select one at random each time typeid is
    >invoked?
    >
    >Perhaps support for dynamic libraries might sometimes lead to the existence of
    >two typeid objects for the same type.


    It does under Windows. Call typeid on the same (non-exported) type in
    a DLL and a exe, and the object returned will be different. This is
    also why MS's dynamic_cast implementation is so slow - it performs
    string comparisons to work out whether two types are the same, whereas
    under Unix I think address comparisons are usually sufficient.

    Tom
    Tom Widmer, Oct 28, 2004
    #15
  16. Dear all,

    > >Perhaps support for dynamic libraries might sometimes lead to the

    existence of
    > >two typeid objects for the same type.

    >
    > It does under Windows. Call typeid on the same (non-exported) type in
    > a DLL and a exe, and the object returned will be different. This is
    > also why MS's dynamic_cast implementation is so slow - it performs
    > string comparisons to work out whether two types are the same, whereas
    > under Unix I think address comparisons are usually sufficient.


    Is it guaranteed that a type_info object stays "in place" in one compilation
    unit? Means, if I have a pointer to type_info object, is this pointer valid
    until the end of the program ?

    Patrick
    Patrick Kowalzick, Oct 28, 2004
    #16
  17. Marco Jez

    Tom Widmer Guest

    On Thu, 28 Oct 2004 15:16:44 +0200, "Patrick Kowalzick"
    <> wrote:

    >Dear all,
    >
    >> >Perhaps support for dynamic libraries might sometimes lead to the

    >existence of
    >> >two typeid objects for the same type.

    >>
    >> It does under Windows. Call typeid on the same (non-exported) type in
    >> a DLL and a exe, and the object returned will be different. This is
    >> also why MS's dynamic_cast implementation is so slow - it performs
    >> string comparisons to work out whether two types are the same, whereas
    >> under Unix I think address comparisons are usually sufficient.

    >
    >Is it guaranteed that a type_info object stays "in place" in one compilation
    >unit? Means, if I have a pointer to type_info object, is this pointer valid
    >until the end of the program ?


    I think the only exception to the would be if you loaded a DLL, got a
    typeid object out of it, and then unloaded the DLL. The standard
    guarantees that type_info objects have static storage duration, so
    except where a compiler is deviating from the standard (as with DLLs),
    type_info object references and pointers are valid for the duration of
    the program.

    Tom
    Tom Widmer, Oct 28, 2004
    #17
  18. Hi Tom,

    > I think the only exception to the would be if you loaded a DLL, got a
    > typeid object out of it, and then unloaded the DLL. The standard
    > guarantees that type_info objects have static storage duration, so
    > except where a compiler is deviating from the standard (as with DLLs),
    > type_info object references and pointers are valid for the duration of
    > the program.


    Do you have a reference in the standard? I do not doubt your words, but I
    searched this before posting and I was not able too find the relevant
    paragraphs (like so often).

    Thanks,
    Patrick
    Patrick Kowalzick, Oct 28, 2004
    #18
  19. Patrick Kowalzick wrote:
    >> I think the only exception to the would be if you loaded a DLL, got a
    >> typeid object out of it, and then unloaded the DLL. The standard
    >> guarantees that type_info objects have static storage duration, so
    >> except where a compiler is deviating from the standard (as with DLLs),
    >> type_info object references and pointers are valid for the duration of
    >> the program.

    >
    > Do you have a reference in the standard? I do not doubt your words, but I
    > searched this before posting and I was not able too find the relevant
    > paragraphs (like so often).
    >


    Victor already mentioned 5.2.8 a couple of messages higher in this
    thread. 5.2.8/1 explicitly states that the lifetime of the object
    referred by the result of 'typeid' extends to the end of the program.

    --
    Best regards,
    Andrey Tarasevich
    Andrey Tarasevich, Oct 28, 2004
    #19
  20. > Victor already mentioned 5.2.8 a couple of messages higher in this
    > thread. 5.2.8/1 explicitly states that the lifetime of the object
    > referred by the result of 'typeid' extends to the end of the program.


    Ups. Sorry.

    Regards,
    Patrick
    Patrick Kowalzick, Oct 28, 2004
    #20
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Dave Theese

    typeid and polymorphic classes

    Dave Theese, Sep 8, 2003, in forum: C++
    Replies:
    5
    Views:
    561
    Govindan
    Sep 8, 2003
  2. Andreas Sch.

    typeid and dynamic_cast, gcc 3.3

    Andreas Sch., Jan 23, 2004, in forum: C++
    Replies:
    18
    Views:
    1,878
    Janusz Szpilewski
    Jan 29, 2004
  3. Jamie Burns
    Replies:
    11
    Views:
    8,958
    Nick Hounsome
    Jan 29, 2004
  4. Mike

    RTTI typeid question

    Mike, May 28, 2004, in forum: C++
    Replies:
    3
    Views:
    3,962
  5. Sarath

    Overloading typeid operator

    Sarath, Feb 27, 2008, in forum: C++
    Replies:
    2
    Views:
    801
    Sarath
    Feb 27, 2008
Loading...

Share This Page