By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
446,194 Members | 884 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 446,194 IT Pros & Developers. It's quick & easy.

typeid ... more

P: n/a

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?

Dec 17 '05 #1
Share this Question
Share on Google+
6 Replies


P: n/a
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/com...cc1fde5e0e17a3

Dec 17 '05 #2

P: n/a
In article <11**********************@o13g2000cwo.googlegroups .com>,
"Neelesh Bodas" <ne***********@gmail.com> 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/com...cc1fde5e0e17a3


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
Dec 17 '05 #3

P: n/a
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;
}
};

Dec 17 '05 #4

P: n/a
In article <11**********************@g47g2000cwa.googlegroups .com>,
"ma740988" <ma******@gmail.com> 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
Dec 17 '05 #5

P: n/a

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.

Dec 18 '05 #6

P: n/a

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.

Dec 18 '05 #7

This discussion thread is closed

Replies have been disabled for this discussion.