typeid ... more

Discussion in 'C++' started by ma740988, Dec 17, 2005.

  1. ma740988

    ma740988 Guest

    I was trying to garner a feel for typeid and it's use with polymorphic
    types

    #include <iostream>

    template <class T>
    bool is_polymorphic() {
    bool result(false);
    typeid( (result=true), *(T*)0);
    return result;
    }

    struct non_polymorphic {};
    struct polymorphic { virtual ~polymorphic() {} };


    int main() {
    std::cout << is_polymorphic<int>() << '\n';
    std::cout << is_polymorphic<non_polymorphic>() << '\n';
    std::cout << is_polymorphic<polymorphic>() << '\n'; //
    3
    }

    ..NET throws an bad_typeid exception when it encounters the line ' //3.
    The exception:

    // file dbgheap.c
    pvBlk = _heap_alloc_dbg(nSize, nBlockUse, szFileName, nLine);

    Now the use of typeid " typeid( (result=true), *(T*)0); " - seems
    funny to me so I'm still trying to understand it, nonetheless the
    question: Why would I get a bad_typeid exception here?


    Perhaps OT hence my apologies upfront.
    The entire boost library if memory serves is 7 mebibytes when built.
    It's appears that because of all the dependencies, it's not possible
    for me to pick out piece parts - for instance the serialization (at
    present that's all I'm interested in using) library. Am I incorrect on
    this?
    ma740988, Dec 17, 2005
    #1
    1. Advertising

  2. ma740988 wrote:
    > I was trying to garner a feel for typeid and it's use with polymorphic
    > types
    >
    > #include <iostream>
    >
    > template <class T>
    > bool is_polymorphic() {
    > bool result(false);
    > typeid( (result=true), *(T*)0);
    > return result;
    > }
    >
    > struct non_polymorphic {};
    > struct polymorphic { virtual ~polymorphic() {} };
    >
    >
    > int main() {
    > std::cout << is_polymorphic<int>() << '\n';
    > std::cout << is_polymorphic<non_polymorphic>() << '\n';
    > std::cout << is_polymorphic<polymorphic>() << '\n'; //
    > 3
    > }
    >
    > .NET throws an bad_typeid exception when it encounters the line ' //3.
    > The exception:
    >
    > // file dbgheap.c
    > pvBlk = _heap_alloc_dbg(nSize, nBlockUse, szFileName, nLine);
    >
    > Now the use of typeid " typeid( (result=true), *(T*)0); " - seems
    > funny to me so I'm still trying to understand it, nonetheless the
    > question: Why would I get a bad_typeid exception here?


    Works well on Comeau online, must be the compiler's internal error.

    Few days ago, Alf wrote a very informative reply explaining the
    behaviour of such a function. It can be found at
    http://groups.google.co.in/group/comp.lang.c /msg/87cc1fde5e0e17a3
    Neelesh Bodas, Dec 17, 2005
    #2
    1. Advertising

  3. In article <>,
    "Neelesh Bodas" <> wrote:

    > ma740988 wrote:
    > > I was trying to garner a feel for typeid and it's use with polymorphic
    > > types
    > >
    > > #include <iostream>
    > >
    > > template <class T>
    > > bool is_polymorphic() {
    > > bool result(false);
    > > typeid( (result=true), *(T*)0);
    > > return result;
    > > }
    > >
    > > struct non_polymorphic {};
    > > struct polymorphic { virtual ~polymorphic() {} };
    > >
    > >
    > > int main() {
    > > std::cout << is_polymorphic<int>() << '\n';
    > > std::cout << is_polymorphic<non_polymorphic>() << '\n';
    > > std::cout << is_polymorphic<polymorphic>() << '\n'; //
    > > 3
    > > }
    > >
    > > .NET throws an bad_typeid exception when it encounters the line ' //3.
    > > The exception:
    > >
    > > // file dbgheap.c
    > > pvBlk = _heap_alloc_dbg(nSize, nBlockUse, szFileName, nLine);
    > >
    > > Now the use of typeid " typeid( (result=true), *(T*)0); " - seems
    > > funny to me so I'm still trying to understand it, nonetheless the
    > > question: Why would I get a bad_typeid exception here?

    >
    > Works well on Comeau online, must be the compiler's internal error.
    >
    > Few days ago, Alf wrote a very informative reply explaining the
    > behaviour of such a function. It can be found at
    > http://groups.google.co.in/group/comp.lang.c /msg/87cc1fde5e0e17a3


    In Addition to Alf's good comments, 5.2.8p2 specifically mentions that
    if the expression in a typeid is a polymorphic class type obtained from
    dereferencing a pointer, and that pointer is null, the typeid expression
    throws a bad_typeid. Sounds like .NET is spot on.

    -Howard
    Howard Hinnant, Dec 17, 2005
    #3
  4. ma740988

    ma740988 Guest

    Neelesh, Howard, thanks for the comment.

    Neelesh, from the looks of Howards comment. It sounds like something
    is amiss about Comeau (though I haven't tried it).

    || Sounds like .NET is spot on.
    OK!!

    > template<class T> bool is_polymorphic( const T&r )
    > {
    > bool result = false;
    > typeid(result = true, r);
    > return result;
    > }


    The thing that puzzles me when I review this line: " typeid(result =
    true, r); " is the fact that the expression makes no use of the the
    type being evaluated. Am I reading this wrong?

    For instance here I make use of the type within typeid.
    class any
    {
    void* obj;
    std::type_info type;
    public:
    template <typename T>
    any(const T& t)
    {
    obj = (void*)(new T(t));
    type = typeid(T); //<------- NOTE: type T here
    }

    template <typename T>
    T& whatever_cast()
    {
    if(typeid(T) != type) //<------- ditto
    throw bad_whatever_cast;
    return *(T*)obj;
    }
    };
    ma740988, Dec 17, 2005
    #4
  5. In article <>,
    "ma740988" <> wrote:

    > Neelesh, Howard, thanks for the comment.
    >
    > Neelesh, from the looks of Howards comment. It sounds like something
    > is amiss about Comeau (though I haven't tried it).


    Comeau online doesn't execute, it only compiles. So I wouldn't expect
    it to throw any exceptions.

    > > template<class T> bool is_polymorphic( const T&r )
    > > {
    > > bool result = false;
    > > typeid(result = true, r);
    > > return result;
    > > }

    >
    > The thing that puzzles me when I review this line: " typeid(result =
    > true, r); " is the fact that the expression makes no use of the the
    > type being evaluated. Am I reading this wrong?


    It's time to plunk down $18 US for a pdf of the standard. Not so that
    you can read it cover to cover, but so that you can look things up:

    http://webstore.ansi.org/

    5.2.8p3 says that if the typeid expression refers to something other
    than an lvalue of a polymorphic type, it is not evaluated. So when "r"
    is not polymorphic, "result=true" is never executed. It's a pretty cute
    trick.

    Note that Alf showed how this information (is_polymorphic) can usually
    be obtained at compile time (as opposed to run time). Indeed, boost has
    a compile time is_polymorphic. And is_polymorphic has subsequently been
    voted into the first library technical report and may already be in
    namespace std::tr1 in your tool set. I am hopeful that it will be fully
    standardized and placed into namespace std for C++0X.

    In gcc (4.0 and later) this prints out:

    #include <iostream>
    #include <typeinfo>
    #include <tr1/type_traits>

    struct non_polymorphic {};
    struct polymorphic { virtual ~polymorphic() {} };

    int main() {
    std::cout << std::tr1::is_polymorphic<int>::value << '\n';
    std::cout << std::tr1::is_polymorphic<non_polymorphic>::value << '\n';
    std::cout << std::tr1::is_polymorphic<polymorphic>::value << '\n';
    }

    0
    0
    1

    The cool thing about this being a compile time value is that you can
    make compile time decisions with this knowledge (such as select
    different algorithms based on compile time polymorphism).

    #include <iostream>
    #include <typeinfo>
    #include <tr1/type_traits>

    struct non_polymorphic {};
    struct polymorphic { virtual ~polymorphic() {} };

    void test(std::tr1::true_type)
    {
    std::cout << "I'm polymorphic\n";
    }

    void test(std::tr1::false_type)
    {
    std::cout << "I'm not polymorphic\n";
    }

    int main() {
    test(std::tr1::is_polymorphic<int>());
    test(std::tr1::is_polymorphic<non_polymorphic>());
    test(std::tr1::is_polymorphic<polymorphic>());
    }

    I'm not polymorphic
    I'm not polymorphic
    I'm polymorphic

    No virtual function calls above. Overload resolution binds things at
    compile time. When test() is inlined, that can make a world of
    difference (but I digress...).

    -Howard
    Howard Hinnant, Dec 17, 2005
    #5
  6. ma740988

    ma740988 Guest

    Howard,

    || So when "r" is not polymorphic, "result=true" is never executed.
    || It's a pretty cute trick.

    Lost sight of r for a minute ... Thanks.. I'm with you now.
    ma740988, Dec 18, 2005
    #6
  7. ma740988 wrote:
    > Neelesh, Howard, thanks for the comment.
    >
    > Neelesh, from the looks of Howards comment. It sounds like something
    > is amiss about Comeau (though I haven't tried it).
    >


    Comeau online doesnot execute, it just compiles.
    I was under impression that your compiler is giving compile-time error.
    Missed that bad_typeid part. Apologies.
    Neelesh Bodas, Dec 18, 2005
    #7
    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:
    556
    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,858
    Janusz Szpilewski
    Jan 29, 2004
  3. Jamie Burns
    Replies:
    11
    Views:
    8,924
    Nick Hounsome
    Jan 29, 2004
  4. Michael
    Replies:
    4
    Views:
    396
    Matt Hammond
    Jun 26, 2006
  5. Robert Klemme

    With a Ruby Yell: more, more more!

    Robert Klemme, Sep 28, 2005, in forum: Ruby
    Replies:
    5
    Views:
    202
    Jeff Wood
    Sep 29, 2005
Loading...

Share This Page