Assume a wrapper class is provided
class Example
{
public:
Example()
{
std::cout << "hello\n";
}
Example(const Example& e)
{
std::cout << "copy\n";
counter++;
}
~Example()
{
std::cout << "bye\n";
}
Example& count()
{
std::cout << "Count: " << counter << std::endl;
return *this;
}
static int counter;
};
int Example::counter = 0;
which is exposed to python using
using namespace boost::python;
class_<Example>("Example", init<>())
.def("count", &Example::count, return_value_policy<copy_non_const_reference>());
now if i execute the following python code
obj=Example()
obj.count().count()
I get
hello
Count: 0
copy
Count: 1
copy
bye
which means boost python is using the copy constructor.
My questions:
If I use boost::noncopyable, then the copy constructor is not called. However, in this case I cannot execute my python code as it complains about a to_python converter (see below). Is there way to fix this?
TypeError: No to_python (by-value) converter found for C++ type: class Example
The copy constructor is called because return_value_policy<copy_non_const_reference>()
is being set and by boost docs:
copy_non_const_reference is a model of ResultConverterGenerator which can be used to wrap C++ functions returning a reference-to-non-const type such that the referenced value is copied into a new Python object.
It complains because the return value is required to be copied but at the same time the class is noncopyable
so the default converter is not found.
To fix this either don't use return_value_policy<copy_non_const_reference>()
or define your custom to_python
converter.