Replies: 1 comment 1 reply
-
If I understand your problem correctly, you want to implicitly cast a python set to a specific Child, when you are calling |
Beta Was this translation helpful? Give feedback.
1 reply
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
-
I have a C++ library with a class hierarchy one segment of which has something like this:
Base -> Child
where Base is an abstract C++ class. In fact, there are many children of Base, Child1, Child2, etc. but this is not super pertinent to my current question. There are many functions in the library that take a
const Base& b
argument which are called with children types and that use virtual function dispatch, and this all works fine on the C++ side of things. I would like to export all of these functions to python using nanobind as well as all of the children classes so that these functions can be called with an instance of an exported child on the python side. This all currently works fine with nanobind.On the other hand, it also makes sense to call these functions with an
const std::set<int>&
type argument. Each of the children in fact have constructors withconst std::set<int>&
arguments. On the python side, I'd like to be able to call the functions directly with python sets of ints, i.e., things like{0,1,2,3,4}
. Currently, this can be done by first explicitly creating one of the children and then calling the function. This also works fine, but what I would like to do is avoid forcing the python programmer to do the explicit conversion to a child first before calling one of the functions that takes aconst Base&b
argument directly. Rather, I'd like to have a default conversion pathway so that the functions taking aconst Base&b
can be called directly with a python set, even if it is only a syntactic ability (i.e., I don't mind a conversion going on to one of the children so-designated behind the scenes).Obviously, I can't export an
nb::init<const std::set<int>&>()
method for Base since Base is abstract. I can also create a GrandChild class which is a child of Child, and use ananobind::detail::type_caster
to automatically convert from anb::set
(i.e., python set) to astd::set<int>
, but this conversion does not happen for functions with arguments of typeconst Base&b
. The conversion does work for functions with arguments of typeconst GrandChild& gc
but that would mean on the C++ side having a version of every function that takes aconst Base&b
also have an overloaded function that takes corresponding arguments of typeconst GrandChild& gc
(as there are many of these functions, this is quite undesirable and harder to maintain).Hence, my question is if in nanobind there is some way to use all of the functions that take a
const Base&b
argument have python sets automatically converted using some default conversion pathway (i.e., using one of the Child classes which can be designated and hard-coded but done implicitly on the python side)? I've looked at trampolines docs but that does not seem to be the right approach, but then I'm not sure.Also note that this is possible to do strictly on the C++ side using C++'s "universal reference" or "forwarding reference" mechanism, but that I do not think helps on the python side with the above, and it would mean doing this for every function in question.
Here is some simple example code that concretely demonstrates the question:
and here is some python code demonstrating the problem:
Thanks very much for any ideas!
Beta Was this translation helpful? Give feedback.
All reactions