Reputation: 1662
What is the appropriate nanobind
syntax to expose the instance method below?
struct Foo {
int &value() & {
return v;
};
int v;
};
With pybind
, one could use static_cast
with Foo::*
syntax to cast the function pointer to the appropriate type, like so:
nb::class_<Foo>(m, "Foo").def("value", static_cast<int &(Foo::*)() &>(&Foo::value));
but with nanobind
, I get this error:
...third_party/nanobind/include/nanobind/nb_class.h:567:28: error: no matching
function for call to 'cpp_function_def<Foo>(int& (Foo::*)() &, nanobind::scope,
nanobind::name, nanobind::is_method)'
567 | cpp_function_def<T>((detail::forward_t<Func>) f, scope(*this),
| ~~~~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
568 | name(name_), is_method(), extra...);
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Do I need some sort of wrapper class with a non-ref-qualified method?
Upvotes: 0
Views: 74
Reputation: 401
If you're comfortable about unspecified behaviors (which mostly means you can rely on it if you have tested it on your target platforms with your target toolchain), you can just use a reinterpret_cast
, as the standard states:
A prvalue of type “pointer to member of X of type T1” can be explicitly converted to a prvalue of a different type “pointer to member of Y of type T2” if T1 and T2 are both function types or both object types. The null member pointer value ([conv.mem]) is converted to the null member pointer value of the destination type. The result of this conversion is unspecified, except in the following cases
nb::class_<Foo>(m, "Foo").def("value", reinterpret_cast<int &(Foo::*)()>(&Foo::value));
But I guess it is better to just implement it using a well-behaved lambda:
nb::class_<Foo>(m, "Foo").def("value", [](Foo* self) { return self->value(); });
It avoids the weird intricacies of casting in C++, and works just as fine.
Upvotes: 1