This is the mail archive of the
gcc@gcc.gnu.org
mailing list for the GCC project.
dynamic_cast<X<T> &> within X<T>::mf(...) doesn't compile
- To: egcs at cygnus dot com, egcs-bugs at cygnus dot com
- Subject: dynamic_cast<X<T> &> within X<T>::mf(...) doesn't compile
- From: Christian Millour <chris at etca dot fr>
- Date: Mon, 20 Oct 1997 10:52:59 +0200 (MET DST)
Hi all.
The form
dynamic_cast<Derived<T> const &>(rhs).xxx...
doesn't compile within a member function of Derived<T>. As a
workaround one may use
dynamic_cast<Derived<T> const *>(&rhs)->xxx...
instead.
The reference form is accepted within members of non-template
classes, or outside of members for template classes.
Test program hereafter. Regards,
--Christian.
osiris:/homeosiris/cepia/cmillour/tests:\> e++ -Wall -pedantic refdc.cc -o refdc
refdc.cc: In method `bool Derived<int>::operator ==<int>(const class Base<int> &) const':
refdc.cc:33: no match for `*const Derived<int> &'
refdc.cc:33: warning: control reaches end of non-void function `Derived<int>::operator ==<int>(const Base<int> &) const'
refdc.cc: In method `bool NTBDerived<int>::operator ==<int>(const class IBase &) const':
refdc.cc:97: no match for `*const NTBDerived<int> &'
refdc.cc:97: warning: control reaches end of non-void function `NTBDerived<int>::operator ==<int>(const IBase &) const'
osiris:/homeosiris/cepia/cmillour/tests:\> e++ -DWORKAROUND -Wall -pedantic refdc.cc -o refdc
osiris:/homeosiris/cepia/cmillour/tests:\> e++ -v
Reading specs from /homeosiris/cepia/cmillour/egcs/lib/gcc-lib/sparc-sun-solaris2.5/egcs-2.90.13/specs
gcc version egcs-2.90.13 971016 (gcc2-970802 experimental)
osiris:/homeosiris/cepia/cmillour/tests:\> cat refdc.cc
#include <iostream.h>
// template base, template derived
template <class T>
class Base {
public:
virtual ~Base();
virtual T a() const = 0;
virtual bool operator==(Base<T> const &) const = 0;
};
template <class T>
Base<T>::~Base()
{
}
template <class T>
class Derived : public Base<T> {
public:
Derived(T val) : m_val(val) {}
T a() const { return m_val; }
bool operator==(Base<T> const &) const;
private:
T m_val;
};
template <class T>
bool
Derived<T>::operator==(Base<T> const & rhs) const {
#ifdef WORKAROUND
return m_val == dynamic_cast<Derived<T> const *>(&rhs)->m_val;
#else
return m_val == dynamic_cast<Derived<T> const &>(rhs).m_val;
#endif
}
// non-template base, non-template derived
class IBase {
public:
virtual ~IBase();
virtual int a() const = 0;
virtual bool operator==(IBase const &) const = 0;
};
IBase::~IBase()
{
}
class IDerived : public IBase {
public:
IDerived(int val) : m_val(val) {}
int a() const { return m_val; }
bool operator==(IBase const &) const;
private:
int m_val;
};
bool
IDerived::operator==(IBase const & rhs) const {
return m_val == dynamic_cast<IDerived const &>(rhs).m_val;
}
// template base, non-template derived
class TBIDerived : public Base<int> {
public:
TBIDerived(int val) : m_val(val) {}
int a() const { return m_val; }
bool operator==(Base<int> const &) const;
private:
int m_val;
};
bool
TBIDerived::operator==(Base<int> const & rhs) const {
return m_val == dynamic_cast<TBIDerived const &>(rhs).m_val;
}
// non-template base, template derived
template <class T>
class NTBDerived : public IBase {
public:
NTBDerived(int val) : m_val(val) {}
T a() const { return m_val; }
bool operator==(IBase const &) const;
private:
T m_val;
};
template <class T>
bool
NTBDerived<T>::operator==(IBase const & rhs) const {
#ifdef WORKAROUND
return m_val == dynamic_cast<NTBDerived<T> const *>(&rhs)->m_val;
#else
return m_val == dynamic_cast<NTBDerived<T> const &>(rhs).m_val;
#endif
}
int
main()
{
#define TH(B,D) \
{ \
D const d(20); \
B const & b = d; \
cerr << dynamic_cast<D const &>(b).a() << endl; \
D const d2(20); \
cerr << (d == d2) << endl; \
}
TH(Base<int>, Derived<int>)
TH(IBase, IDerived)
TH(Base<int>, TBIDerived)
TH(IBase, NTBDerived<int>)
}
osiris:/homeosiris/cepia/cmillour/tests:\>