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