@@ -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
@@ -2560,62 +2565,96 @@ Class binding
25602565 constructor. It is only meant to be used in binding declarations done via
25612566 :cpp:func: `class_::def() `.
25622567
2563- Sometimes, it is necessary to bind constructors that don't exist in the
2564- underlying C++ type (meaning that they are specific to the Python bindings).
2565- Because `init ` only works for existing C++ constructors, this requires
2566- a manual workaround noting that
2567-
2568- .. code-block :: cpp
2569-
2570- nb::class_<MyType>(m, "MyType")
2571- .def(nb::init<const char*, int>());
2572-
2573- is syntax sugar for the following lower-level implementation using
2574- "`placement new <https://en.wikipedia.org/wiki/Placement_syntax >`_":
2568+ To bind a constructor that exists in the C++ class, taking ``Args... ``, write
2569+ ``nb::init<Args...>() ``.
2570+
2571+ To bind a constructor that is specific to the Python bindings (a
2572+ "custom constructor"), write ``nb::init(<some function>) `` (write a
2573+ lambda expression or a function pointer inside the
2574+ parentheses). The function should return a prvalue of the bound
2575+ type, by ending with a statement like ``return MyType(some,
2576+ args); ``. If you write a custom constructor in this way, then
2577+ nanobind can construct the object without any extra copies or
2578+ moves, and the object therefore doesn't need to be copyable or movable.
2579+
2580+ If your custom constructor needs to take some actions after constructing
2581+ the C++ object, then nanobind recommends that you eschew
2582+ :cpp:struct: `nb::init() <init> ` and instead bind an ``__init__ `` method
2583+ directly. By convention, any nanobind method named ``"__init__" `` will
2584+ receive as its first argument a pointer to uninitialized storage that it
2585+ can initialize using `placement new
2586+ <https://en.wikipedia.org/wiki/Placement_syntax> `_:
25752587
25762588 .. code-block :: cpp
25772589
25782590 nb::class_<MyType>(m, "MyType")
25792591 .def("__init__",
25802592 [](MyType* t, const char* arg0, int arg1) {
25812593 new (t) MyType(arg0, arg1);
2594+ t->doSomething();
25822595 });
25832596
25842597 The provided lambda function will be called with a pointer to uninitialized
25852598 memory that has already been allocated (this memory region is co-located
25862599 with the Python object for reasons of efficiency). The lambda function can
25872600 then either run an in-place constructor and return normally (in which case
25882601 the instance is assumed to be correctly constructed) or fail by raising an
2589- exception.
2602+ exception. If an exception is raised, nanobind assumes the object *was not *
2603+ constructed; in the above example, if ``doSomething() `` could throw, then you
2604+ would need to take care to call the destructor explicitly (``t->~MyType(); ``)
2605+ in case of an exception after the C++ constructor had completed.
2606+
2607+ When binding a custom constructor using :cpp:struct: `nb::init() <init> ` for
2608+ a type that supports :ref: `overriding virtual methods in Python
2609+ <trampolines>`, you must return either an instance of the trampoline
2610+ type (``PyPet `` in ``nb::class_<Pet, PyPet>(...) ``) or something that
2611+ can initialize both the bound type and the trampoline type (e.g.,
2612+ you can return a ``Pet `` if there exists a ``PyPet(Pet&&) `` constructor).
2613+ If that's not possible, you can alternatively write :cpp:struct: `nb::init()
2614+ <init> ` with two function arguments instead of one. The first returns
2615+ an instance of the bound type (``Pet ``), and will be called when constructing
2616+ an instance of the C++ class that has not been extended from Python.
2617+ The second returns an instance of the trampoline type (``PyPet ``),
2618+ and will be called when constructing an instance that does need to consider
2619+ the possibility of Python-based virtual method overrides.
2620+
2621+ .. note :: :cpp:struct:`nb::init() <init>` always creates Python ``__init__``
2622+ methods, which construct a C++ object in already-allocated Python object
2623+ storage. If you need to wrap a constructor that performs its own
2624+ allocation, such as a factory function that returns a pointer, you must
2625+ use :cpp:struct: `nb::new_() <new_> ` instead in order to create a Python
2626+ ``__new__ `` method.
25902627
25912628.. cpp :struct :: template <typename Arg> init_implicit
25922629
25932630 See :cpp:class: `init ` for detail on binding constructors. The main
2594- difference between :cpp:class: `init ` and `init_implicit ` is that the latter
2595- only supports constructors taking a single argument `Arg `, and that it marks
2596- the constructor as usable for implicit conversions from `Arg `.
2631+ difference between :cpp:class: `init ` and `init_implicit ` is that the latter
2632+ only supports constructors that exist in the C++ code and take a single
2633+ argument `Arg `, and that it marks the constructor as usable for implicit
2634+ conversions from `Arg `.
25972635
25982636 Sometimes, it is necessary to bind implicit conversion-capable constructors
25992637 that don't exist in the underlying C++ type (meaning that they are specific
2600- to the Python bindings). This can be done manually noting that
2638+ to the Python bindings). This can be done manually, noting that
26012639
26022640 .. code-block :: cpp
26032641
2604- nb::class_<MyType>(m, "MyType")
2605- .def(nb::init_implicit<const char*>());
2642+ nb::class_<MyType>(m, "MyType")
2643+ .def(nb::init_implicit<const char*>());
26062644
26072645 can be replaced by the lower-level code
26082646
26092647 .. code-block :: cpp
26102648
26112649 nb::class_<MyType>(m, "MyType")
2612- .def("__init__",
2613- [](MyType* t, const char* arg0) {
2614- new (t) MyType(arg0);
2615- });
2650+ .def(nb::init<const char*>());
26162651
26172652 nb::implicitly_convertible<const char*, MyType>();
26182653
2654+ and that this transformation works equally well if you use one of the forms
2655+ of :cpp:class: `nb::init() <init> ` that cannot be expressed by
2656+ :cpp:class: `init_implicit `.
2657+
26192658.. cpp :struct :: template <typename Func> new_
26202659
26212660 This is a small helper class that indicates to :cpp:func: `class_::def() `
0 commit comments