Boost.Python returning by internal reference - boost-python

Given two classes:
class B {
// ...
};
class A {
public:
B& b() { return *b_; }
private:
B* b_;
};
In the Boost.Python module, I have
bp::class_<B, boost::noncopyable>(...)...;
which works fine. I also have
bp::class_<A, boost::noncopyable>(...)
.def("b", &A::b,
bp::return_internal_reference<>()
)
but it doesn't compile. It says:
/opt/local/include/boost/python/detail/caller.hpp:102:109: error: 'struct boost::python::detail::reference_existing_object_requires_a_pointer_or_reference_return_type<B>' has no member named 'get_pytype'
But, it should have a pytype, right?

Related

In binding a derived class must I also bind all parent classes to the root class?

True or False
To bind a derived class in a C++ class hierarchy one must also bind all the parent classes on up to the root class.
I'm looking to bind a bunch of custom data types in a project I just started on and am looking to scope out the degree of work involved. I'm looking to bind a class that's 3 levels of derivation away from a root type.
Are there any rules of thumb for when one must also bind the parent classes to successfully bind the child classes?
False
Let us consider a simple example:
#include <string>
class Parent
{
public:
Parent() { m_name = "Parent"; }
std::string foo() { return m_name + "::foo"; }
virtual std::string bar() { return m_name + "::bar"; }
protected:
std::string m_name;
};
class Derived : public Parent
{
public:
Derived() { m_name = "Derived"; }
std::string bar() override { return m_name + "::bar (override)"; }
};
This you can bind the way you describe: bind the parent, the derived class will benefit from all the derived methods (you even don't have to bind the override):
#include <pybind11/pybind11.h>
namespace py = pybind11;
PYBIND11_MODULE(example, m)
{
py::class_<Parent>(m, "Parent")
.def(py::init<>(), "Constructor description")
.def("foo", &Parent::foo, "Function description")
.def("bar", &Parent::bar, "Function description")
.def("__repr__", [](const Parent&) { return "<Parent>"; });
py::class_<Derived, Parent>(m, "Derived")
.def(py::init<>(), "Constructor description")
.def("__repr__", [](const Derived&) { return "<Derived>"; });
}
Indeed
import example
p = example.Parent()
print(p.foo())
print(p.bar())
d = example.Derived()
print(d.foo())
print(d.bar())
will print
Parent::foo
Parent::bar
Derived::foo
Derived::bar (override)
However, if you just want to bind one derived class (you don't care about the parent, nor about any of the other derived classes) you can also just bind the derived class you care about, without ever specifying the parent:
#include <pybind11/pybind11.h>
namespace py = pybind11;
PYBIND11_MODULE(example, m)
{
py::class_<Derived>(m, "Derived")
.def(py::init<>(), "Constructor description")
.def("foo", &Derived::foo, "Function description")
.def("bar", &Derived::bar, "Function description")
.def("__repr__", [](const Derived&) { return "<Derived>"; });
}
Indeed
import example
d = example.Derived()
print(d.foo())
print(d.bar())
prints
Derived::foo
Derived::bar (override)
See the docs for reference.

how to call member methods inside a wrapper class without repeating the method definition inside the wrapper class?

let's assume i have a wrapper class that embeds a single memeber:
class wrapper {
public:
Object obj;
// the rest ...
};
if the member variable obj has some methods, how can i call the member variable method without explicitly defining methods in the wrapper class like this?
class wrapper{
public:
void foo { obj.foo (); }
int bar (int x) {return obj.bar(x); }
};
i know this is doable in python, but how can i have the same functionality in c++?
ps- please note i don't want to inherit from the member class. this wouldn't't be a wrapper class by definition. i want to achieve this through composition instead.
There are a few ways to handle this. One would be to create a getter to return the wrapper object and another is to override the typecast operator:
class Object {
public:
void foo() {cout << "test" << endl;}
};
class wrapper {
protected:
Object obj;
public:
operator Object&() {return obj;}
Object& getObject() {return obj;}
};
void f(A& a) {
a.foo();
}
int main() {
wrapper w;
((Object)w).foo();
w.getObject().foo();
f(w);
return 0;
}
As you can see, the typecast operator requires you to cast the wrapper object, except when passing as a parameter to the function f().
Also, in your example you already have the obj member as public so it is exposed. You could just:
wrapper w;
w.obj.foo();
Here's a discussion on that: What good are public variables then?

Swift: how to understand dynamic method dispatching in init method?

I find that the dynamic method dispatching in init method of Swift is different from which in C++, can anyone explain why?
This is the demo code and its output:
In Swift:
class Object {
init() {
a()
}
func a() {
print("Object")
}
}
class SubObject: Object {
override init() {
}
override func a() {
print("SubObject")
}
}
let a = SubObject()
// output: SubObject
In C++:
class Object {
public:
Object() {
a();
}
virtual void a() {
std::cout << "Object" << std::endl;
}
};
class SubObject: public Object {
public:
SubObject() {
}
virtual void a() {
std::cout << "SubObject" << std::endl;
}
};
int main(int argc, const char * argv[]) {
SubObject s;
return 0;
}
// output: Object
As you can see, these code above write in Swift and C++ are nearly the same, but their output is quite different, while Swift seems that it finds the override method and called the derived one, the C++ still called the super's.
Here at LearnCpp, it says:
Do not call virtual functions from constructors or destructors Here’s another gotcha that often catches unsuspecting new programmers. You should not call virtual functions from constructors or destructors. Why?
Remember that when a Derived class is created, the Base portion is constructed first. If you were to call a virtual function from the Base constructor, and Derived portion of the class hadn’t even been created yet, it would be unable to call the Derived version of the function because there’s no Derived object for the Derived function to work on.
In C++, it will call the Base version instead.
A similar issue exists for destructors. If you call a virtual function in a Base class destructor, it will always resolve to the Base class version of the function, because the Derived portion of the class will already have been destroyed.

final interface implementation not recognized from interface base list

How can a method from the InterfaceBaseList be implemented in the current interface ? Example:
interface bar(T)
{
void method1(T a);
void method2(T a);
}
interface baz: bar!int
{
final void method1(int a){}
}
class foo: baz
{
this(){method1(0);}
void method2(int a){}
}
void main()
{
auto Foo = new foo;
Foo.method2(0);
}
outputs:
myfile.d(xx): Error: foo interface function 'void method1(int a)'
is not implemented
It seems that the compiler doesnt get that baz.method1 is actually bar.method1.
Note that the example illustrates that in baz, for some reasons, we know that method1 will always have the same implemtation. a baz implementer mays be down-casted as a bar (so making a dummy final method1 in bar is not possible).
Interfaces can only declare virtual members without implementation, or final members with implementation. Your code is attempting to override a virtual method with a non-virtual implementation. Due to the nature of interfaces, you cannot actually override anything within them. What you want instead is an abstract class.
abstract class baz: bar!int
{
override void method1(int a){}
}
Replacing your baz interface with the above class will clear up the issue.
As an example of why this isn't allowed, consider this code: (Does not compile, of course!)
interface Root {
int foo();
}
interface BranchA : Root {
override int foo() { return 1; }
}
interface BranchB : Root {
override int foo() { return 2; }
}
class C : BranchA, BranchB { }
What would (new C()).foo() return? The result is ambiguous. It is only acceptable to override the interface methods in a class, because unlike interfaces, you can only inherit one class at a time.

How to inherit classes that inherits base class more than once

Title is not clear. Here I am explaining
I am having a package say package provide test. It is having classes. I am using Itcl. Package is having following structure
::itcl::class classA {
written something having constructor and methods
}
::itcl::class classB {
inherit ::test::classA
having its own constructor and methods
}
::itcl::class classC {
inherit ::test::classA
having its own constructor and methods
}
::itcl::class classD {
inehrit ::test::classB ::test::classC
having its own constructor and methods
}
When i am requiring package test, I am getting below error
class "::test::classD" inherits base class "::test::classA" more than once:
How can i handle the error
Diamond inheritance is not allowed due to path ambiguity.
I.e.
TopClass
/ \
LeftClass RightClass
\ /
BottomClass
As workaround you can use composition (has-a) rather than inheritance
(is-a).
::itcl::class classA {
}
::itcl::class classB {
inherit ::test::classA
}
::itcl::class classC {
inherit ::test::classA
}
::itcl::class classD {
constructor {} {
set _b [::test::classB #auto]
set _c [::test::classC #auto]
}
destructor {
::itcl::delete $_b
::itcl::delete $_c
}
private {
variable _b ""
variable _c ""
}
}
Now in classD you must be specific to classB or classC path the code gets to base.