typeid ... more

M

ma740988

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?
 
N

Neelesh Bodas

ma740988 said:
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
 
H

Howard Hinnant

"Neelesh Bodas said:
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
 
M

ma740988

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

Howard Hinnant

"ma740988 said:
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.
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
 
M

ma740988

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.
 
N

Neelesh Bodas

ma740988 said:
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.
 

Ask a Question

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

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,744
Messages
2,569,483
Members
44,902
Latest member
Elena68X5

Latest Threads

Top