@@ -2191,9 +2191,14 @@ Class binding
2191
2191
2192
2192
.. cpp :function :: template <typename ... Args, typename ... Extra> class_ &def (init<Args...> arg, const Extra &... extra)
2193
2193
2194
- Bind a constructor. The variable length `extra ` parameter can be used to
2194
+ Bind a C++ constructor that takes parameters of types ``Args... ``.
2195
+ The variable length `extra ` parameter can be used to
2195
2196
pass a docstring and other :ref: `function binding annotations
2196
- <function_binding_annotations>`.
2197
+ <function_binding_annotations>`. You can also bind a custom constructor
2198
+ (one that does not exist in the C++ code) by writing
2199
+ ``.def(nb::init(<lambda>)) ``, provided the lambda returns an instance of
2200
+ the class by value. If you need to wrap a factory function that returns
2201
+ a pointer or shared pointer, see :cpp:struct: `nb::new_() <new_> ` instead.
2197
2202
2198
2203
.. cpp :function :: template <typename Arg, typename ... Extra> class_ &def (init_implicit<Arg> arg, const Extra &... extra)
2199
2204
@@ -2567,62 +2572,96 @@ Class binding
2567
2572
constructor. It is only meant to be used in binding declarations done via
2568
2573
:cpp:func: `class_::def() `.
2569
2574
2570
- Sometimes, it is necessary to bind constructors that don't exist in the
2571
- underlying C++ type (meaning that they are specific to the Python bindings).
2572
- Because `init ` only works for existing C++ constructors, this requires
2573
- a manual workaround noting that
2574
-
2575
- .. code-block :: cpp
2576
-
2577
- nb::class_<MyType>(m, "MyType")
2578
- .def(nb::init<const char*, int>());
2579
-
2580
- is syntax sugar for the following lower-level implementation using
2581
- "`placement new <https://en.wikipedia.org/wiki/Placement_syntax >`_":
2575
+ To bind a constructor that exists in the C++ class, taking ``Args... ``, write
2576
+ ``nb::init<Args...>() ``.
2577
+
2578
+ To bind a constructor that is specific to the Python bindings (a
2579
+ "custom constructor"), write ``nb::init(<some function>) `` (write a
2580
+ lambda expression or a function pointer inside the
2581
+ parentheses). The function should return a prvalue of the bound
2582
+ type, by ending with a statement like ``return MyType(some,
2583
+ args); ``. If you write a custom constructor in this way, then
2584
+ nanobind can construct the object without any extra copies or
2585
+ moves, and the object therefore doesn't need to be copyable or movable.
2586
+
2587
+ If your custom constructor needs to take some actions after constructing
2588
+ the C++ object, then nanobind recommends that you eschew
2589
+ :cpp:struct: `nb::init() <init> ` and instead bind an ``__init__ `` method
2590
+ directly. By convention, any nanobind method named ``"__init__" `` will
2591
+ receive as its first argument a pointer to uninitialized storage that it
2592
+ can initialize using `placement new
2593
+ <https://en.wikipedia.org/wiki/Placement_syntax> `_:
2582
2594
2583
2595
.. code-block :: cpp
2584
2596
2585
2597
nb::class_<MyType>(m, "MyType")
2586
2598
.def("__init__",
2587
2599
[](MyType* t, const char* arg0, int arg1) {
2588
2600
new (t) MyType(arg0, arg1);
2601
+ t->doSomething();
2589
2602
});
2590
2603
2591
2604
The provided lambda function will be called with a pointer to uninitialized
2592
2605
memory that has already been allocated (this memory region is co-located
2593
2606
with the Python object for reasons of efficiency). The lambda function can
2594
2607
then either run an in-place constructor and return normally (in which case
2595
2608
the instance is assumed to be correctly constructed) or fail by raising an
2596
- exception.
2609
+ exception. If an exception is raised, nanobind assumes the object *was not *
2610
+ constructed; in the above example, if ``doSomething() `` could throw, then you
2611
+ would need to take care to call the destructor explicitly (``t->~MyType(); ``)
2612
+ in case of an exception after the C++ constructor had completed.
2613
+
2614
+ When binding a custom constructor using :cpp:struct: `nb::init() <init> ` for
2615
+ a type that supports :ref: `overriding virtual methods in Python
2616
+ <trampolines>`, you must return either an instance of the trampoline
2617
+ type (``PyPet `` in ``nb::class_<Pet, PyPet>(...) ``) or something that
2618
+ can initialize both the bound type and the trampoline type (e.g.,
2619
+ you can return a ``Pet `` if there exists a ``PyPet(Pet&&) `` constructor).
2620
+ If that's not possible, you can alternatively write :cpp:struct: `nb::init()
2621
+ <init> ` with two function arguments instead of one. The first returns
2622
+ an instance of the bound type (``Pet ``), and will be called when constructing
2623
+ an instance of the C++ class that has not been extended from Python.
2624
+ The second returns an instance of the trampoline type (``PyPet ``),
2625
+ and will be called when constructing an instance that does need to consider
2626
+ the possibility of Python-based virtual method overrides.
2627
+
2628
+ .. note :: :cpp:struct:`nb::init() <init>` always creates Python ``__init__``
2629
+ methods, which construct a C++ object in already-allocated Python object
2630
+ storage. If you need to wrap a constructor that performs its own
2631
+ allocation, such as a factory function that returns a pointer, you must
2632
+ use :cpp:struct: `nb::new_() <new_> ` instead in order to create a Python
2633
+ ``__new__ `` method.
2597
2634
2598
2635
.. cpp :struct :: template <typename Arg> init_implicit
2599
2636
2600
2637
See :cpp:class: `init ` for detail on binding constructors. The main
2601
- difference between :cpp:class: `init ` and `init_implicit ` is that the latter
2602
- only supports constructors taking a single argument `Arg `, and that it marks
2603
- the constructor as usable for implicit conversions from `Arg `.
2638
+ difference between :cpp:class: `init ` and `init_implicit ` is that the latter
2639
+ only supports constructors that exist in the C++ code and take a single
2640
+ argument `Arg `, and that it marks the constructor as usable for implicit
2641
+ conversions from `Arg `.
2604
2642
2605
2643
Sometimes, it is necessary to bind implicit conversion-capable constructors
2606
2644
that don't exist in the underlying C++ type (meaning that they are specific
2607
- to the Python bindings). This can be done manually noting that
2645
+ to the Python bindings). This can be done manually, noting that
2608
2646
2609
2647
.. code-block :: cpp
2610
2648
2611
- nb::class_<MyType>(m, "MyType")
2612
- .def(nb::init_implicit<const char*>());
2649
+ nb::class_<MyType>(m, "MyType")
2650
+ .def(nb::init_implicit<const char*>());
2613
2651
2614
2652
can be replaced by the lower-level code
2615
2653
2616
2654
.. code-block :: cpp
2617
2655
2618
2656
nb::class_<MyType>(m, "MyType")
2619
- .def("__init__",
2620
- [](MyType* t, const char* arg0) {
2621
- new (t) MyType(arg0);
2622
- });
2657
+ .def(nb::init<const char*>());
2623
2658
2624
2659
nb::implicitly_convertible<const char*, MyType>();
2625
2660
2661
+ and that this transformation works equally well if you use one of the forms
2662
+ of :cpp:class: `nb::init() <init> ` that cannot be expressed by
2663
+ :cpp:class: `init_implicit `.
2664
+
2626
2665
.. cpp :struct :: template <typename Func> new_
2627
2666
2628
2667
This is a small helper class that indicates to :cpp:func: `class_::def() `
0 commit comments