templates, derived classes, and dynamic_cast
Chris Mason
cmason@cmu.edu
Wed Mar 15 21:28:00 GMT 2000
Hello.
I've found something weird involving templates and dynamic_cast, and I
don't know whether it's an error in my program or a deficiency or bug in
g++. Dynamic_casting (a base class pointer to (a template class whose
template parameter is a derived class)) into (a template class pointer
to a (template class whose template parameter is a base class)) fails.
(See sample code below if you couldn't parse that.)
There's nothing in (the 2 Dec 1999 draft version of) the C++ std which
directly discusses dynamic_casting of templates. So I can't say for
sure if this code is or is not correct, as far as the standard is
concerned.
I didn't dream this up. The code is after an article by Andrew Koenig:
Koenig, Andrew. Designing a C++ container class. JOOP February 1992
pg 37.
Test program (which follows, save as simpletest.cpp) outputs:
> ./simpletest
Base worked.
dynamic_cast() failed.
Derived didn't work.
Compile with:
> /usr/local/bin/g++ -Wall -o simpletest simpletest.cpp
simpletest.cpp: In function `int main(int, char **)':
simpletest.cpp:50: warning: initialization of non-const reference `class
Base *&' from rvalue `Base *'
simpletest.cpp:19: warning: in passing argument 1 of
`anyholder::put<Base *>(Base *&)'
simpletest.cpp:56: warning: initialization of non-const reference `class
Derived *&' from rvalue `Derived *'
simpletest.cpp:19: warning: in passing argument 1 of
`anyholder::put<Derived *>(Derived *&)'
This is present in snapshot 20000313:
> /usr/local/bin/g++ -v
Reading specs from /usr/local/lib/gcc-lib/i686-pc-linux-gnu/2.96/specs
gcc version 2.96 20000313 (experimental)
I don't subscribe to this list/newsgroup, so please cc any
correspondance to me.
Thanks for a terrific, if still developing, compiler.
-c
Begin simpletest.cpp:
#include <iostream.h>
class anybase {
public:
virtual ~anybase() {}
};
template <class T> class any : public anybase {
public:
any(const T& t0) : t(t0) {}
const T t;
};
class anyholder {
public:
anybase * b;
template <class T> void put(T& val) {
b = new any<T>(val);
}
template <class T> void get(T& val) {
any<T>* a = dynamic_cast<any<T>*>(b);
if (!a) {
cout << "dynamic_cast() failed.\n";
return;
}
val = a->t;
}
virtual ~anyholder() {}
};
class Base {
public:
virtual ~Base() {}
};
class Derived : public Base {
public:
virtual ~Derived() {}
};
int main (int argc, char ** argv) {
anyholder * ah = new anyholder();
Base * b = NULL;
ah->put(new Base());
ah->get(b);
if (b) cout << "Base worked.\n";
else cout << "Base didn't work.\n";
b = NULL;
ah->put(new Derived());
ah->get(b);
if (b) cout << "Derived worked.\n";
else cout << "Derived didn't work.\n";
return 0;
}
/* End simpletest.cpp */
/*
--
[ Christopher Mason <cmason@cmu.edu>
http://ash.rem.cmu.edu/ ]
[ "Don't you see?! We're actors--we're the opposite of people!"
-Stoppard ]
*/
More information about the Gcc-bugs
mailing list