interrogate & covariant return types

I stumbled upon something I don’t understand, and would like to ask if I am doing it the wrong way, of if this is an missing feature in interrogate.

I have two classes from an external library (Alpha & Beta), with Beta being derived from Alpha. Now I am writing two Panda classes (MySuper, MyDerived). MySuper is abstract, because of the method ptr() which returns an Alpha*. This method is implemented in MyDerived, using a covariant return value (Beta*):

// Imported classes
class Alpha {...};
class Beta : public Alpha {...};

// My classes
class MySuper {
  INLINE virtual Alpha *ptr() const = 0;

class MyDerived : public MySuper {
  INLINE virtual Beta *ptr() const;

My code compiles, but when I make an instance of MyDerived (from a Python script) I get this error:

Seems like interrogate thinks that MyDerived does not implement the pure virtual method MySuper::ptr(), and thus does thinks MyDerived is abstract and does not allow to create instances of MyDerived class.

This does not happen if I do a dummy implementation of the pure virtual method, e. g. like below.

INLINE virtual Alpha *ptr() const { return NULL; };

You C++ programmers and your love of shiny new language features. :wink:

Right, interrogate does not recognize covariant return types as being equivalent. It was written before this feature was added to C++.

(In general, the Panda philosophy is to be as broadly supported as possible, so we try to avoid unnecessary use of very new language features as well.)

I’m not opposed to adding support for this particular feature, but it seems like such a small point, especially because there exist easy workarounds.


Yep, all singing all dancing and state-of-art :wink:

Leaving this improvement away is fine with me, but what kind of workaround do you suggest (I consider myself still a novice C++ programmer)?

My current workaround (implementing the pure virtual function MySuper::ptr still depends on the compiler supporting covariant return types).

Other ideas would be:

  • to offer two different methods, e. g. MySuper::alpha_ptr() and MyDerived::beta_ptr()
  • MyDerived::ptr() also returns an Alpha*, and code calling this function casts the returned pointer from Alpha* to Beta* (I try to avoid casting when possible)

I consider this a perfectly acceptable workaround for your own code that you do not intend to commit to the Panda3D codebase, provided you are happy with the set of compilers that support this language feature.

It may even be acceptable for code destined to become part of Panda, since I’m pretty sure all of our currently-targeted compilers support this feature by now.

Both of these are fine solutions to avoid this language dependency. The latter one is the solution used most often within existing Panda code–and we typically use the DCAST macro to provide runtime-safe casting.


It’s intended to go into the Panda3D codebase, sooner or later. So I will use the DCAST solution. Thank you for helping.