@@ -2191,9 +2191,14 @@ Class binding
21912191
21922192 .. cpp :function :: template <typename ... Args, typename ... Extra> class_ &def (init<Args...> arg, const Extra &... extra)
21932193
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
21952196 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.
21972202
21982203 .. cpp :function :: template <typename Arg, typename ... Extra> class_ &def (init_implicit<Arg> arg, const Extra &... extra)
21992204
@@ -2567,62 +2572,96 @@ Class binding
25672572 constructor. It is only meant to be used in binding declarations done via
25682573 :cpp:func: `class_::def() `.
25692574
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> `_:
25822594
25832595 .. code-block :: cpp
25842596
25852597 nb::class_<MyType>(m, "MyType")
25862598 .def("__init__",
25872599 [](MyType* t, const char* arg0, int arg1) {
25882600 new (t) MyType(arg0, arg1);
2601+ t->doSomething();
25892602 });
25902603
25912604 The provided lambda function will be called with a pointer to uninitialized
25922605 memory that has already been allocated (this memory region is co-located
25932606 with the Python object for reasons of efficiency). The lambda function can
25942607 then either run an in-place constructor and return normally (in which case
25952608 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.
25972634
25982635.. cpp :struct :: template <typename Arg> init_implicit
25992636
26002637 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 `.
26042642
26052643 Sometimes, it is necessary to bind implicit conversion-capable constructors
26062644 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
26082646
26092647 .. code-block :: cpp
26102648
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*>());
26132651
26142652 can be replaced by the lower-level code
26152653
26162654 .. code-block :: cpp
26172655
26182656 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*>());
26232658
26242659 nb::implicitly_convertible<const char*, MyType>();
26252660
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+
26262665.. cpp :struct :: template <typename Func> new_
26272666
26282667 This is a small helper class that indicates to :cpp:func: `class_::def() `
0 commit comments