Discussion:
[C++-sig] virtual functions with default implementation
Stefan Seefeld
2015-08-17 12:03:03 UTC
Permalink
Hi,

I'm reviewing the Boost.Python tutorial, and I'm stumbling over the
section on "Virtual Functions with Default implementations"
(http://boostorg.github.io/python/doc/html/tutorial/tutorial/exposing.html#tutorial.exposing.virtual_functions_with_default_i).
It mentions the need to provide a separate default implementation
function as third argument to "def()", without explaining why that is
needed.
In fact, I'm trying various alternatives (abstract, non-abstract), and I
can't find a need for it. All my tests work fine without it.

Does anyone know why this is needed, and could perhaps even provide a
little test case ?

Thanks,
Stefan
--
...ich hab' noch einen Koffer in Berlin...
Nikolay Mladenov
2015-08-17 18:12:24 UTC
Permalink
If you export an abstract class, create an object from python and call its
virtual from C++ it should not work without the default implementation.
Post by Stefan Seefeld
Hi,
I'm reviewing the Boost.Python tutorial, and I'm stumbling over the
section on "Virtual Functions with Default implementations"
(
http://boostorg.github.io/python/doc/html/tutorial/tutorial/exposing.html#tutorial.exposing.virtual_functions_with_default_i
).
It mentions the need to provide a separate default implementation
function as third argument to "def()", without explaining why that is
needed.
In fact, I'm trying various alternatives (abstract, non-abstract), and I
can't find a need for it. All my tests work fine without it.
Does anyone know why this is needed, and could perhaps even provide a
little test case ?
Thanks,
Stefan
--
...ich hab' noch einen Koffer in Berlin...
_______________________________________________
Cplusplus-sig mailing list
https://mail.python.org/mailman/listinfo/cplusplus-sig
Stefan Seefeld
2015-08-17 18:39:32 UTC
Permalink
Post by Nikolay Mladenov
If you export an abstract class, create an object from python and call
its virtual from C++ it should not work without the default
implementation.
The tutorial explains that well:

for the case of an abstract base, use

def("func", bpl::pure_virtual(&Base::func))

which will provide an implementation that does nothing but raise a
Python exception to tell the caller that the method isn't implemented.

For the case with default implementation, the tutorial gives this wrapper:

struct BaseWrap : Base, bpl::wrapper<Base>
{
virtual std::string func() const
{
if (bpl::override f = this->get_override("func"))
return f();
else
return Base::func();
}
std::string default_func() const { return this->Base::func();}
};

and it seems to me much more natural to implement the "default" case
directly in the "else" branch above, rather than add it to the "def()" call.

Stefan
Post by Nikolay Mladenov
Hi,
I'm reviewing the Boost.Python tutorial, and I'm stumbling over the
section on "Virtual Functions with Default implementations"
(http://boostorg.github.io/python/doc/html/tutorial/tutorial/exposing.html#tutorial.exposing.virtual_functions_with_default_i).
It mentions the need to provide a separate default implementation
function as third argument to "def()", without explaining why that is
needed.
In fact, I'm trying various alternatives (abstract, non-abstract), and I
can't find a need for it. All my tests work fine without it.
Does anyone know why this is needed, and could perhaps even provide a
little test case ?
Thanks,
Stefan
--
...ich hab' noch einen Koffer in Berlin...
_______________________________________________
Cplusplus-sig mailing list
https://mail.python.org/mailman/listinfo/cplusplus-sig
_______________________________________________
Cplusplus-sig mailing list
https://mail.python.org/mailman/listinfo/cplusplus-sig
--
...ich hab' noch einen Koffer in Berlin...
Alex Mohr
2015-08-17 18:54:34 UTC
Permalink
Post by Stefan Seefeld
struct BaseWrap : Base, bpl::wrapper<Base>
{
virtual std::string func() const
{
if (bpl::override f = this->get_override("func"))
return f();
else
return Base::func();
}
std::string default_func() const { return this->Base::func();}
};
and it seems to me much more natural to implement the "default" case
directly in the "else" branch above, rather than add it to the "def()" call.
I think this might be so that python can invoke the superclass (C++)
implementation directly in its override, but I'm not 100% sure.

Alex
Stefan Seefeld
2015-08-17 21:44:53 UTC
Permalink
Hi Alex,
Post by Alex Mohr
Post by Stefan Seefeld
struct BaseWrap : Base, bpl::wrapper<Base>
{
virtual std::string func() const
{
if (bpl::override f = this->get_override("func"))
return f();
else
return Base::func();
}
std::string default_func() const { return this->Base::func();}
};
and it seems to me much more natural to implement the "default" case
directly in the "else" branch above, rather than add it to the "def()" call.
I think this might be so that python can invoke the superclass (C++)
implementation directly in its override, but I'm not 100% sure.
Ah, that's it !

I just tried

Konsole output
... def func(self): return super(C, self).func()

which yields an infinite recursion (until stack overflow) unless I
define "func" with the additional default function.

Thanks !

Stefan
--
...ich hab' noch einen Koffer in Berlin...
Loading...