mirror of
https://github.com/pybind/pybind11.git
synced 2024-11-22 05:05:11 +00:00
support for brace initialization
This commit is contained in:
parent
fb276c661f
commit
4336a7da4a
@ -492,6 +492,30 @@ you could equivalently write:
|
||||
|
||||
which will invoke the constructor in-place at the pre-allocated memory.
|
||||
|
||||
Brace initialization
|
||||
--------------------
|
||||
|
||||
``pybind11::init<>`` internally uses C++11 brace initialization to call the
|
||||
constructor of the target class. This means that it can be used to bind
|
||||
*implicit* constructors as well:
|
||||
|
||||
.. code-block:: cpp
|
||||
|
||||
struct Aggregate {
|
||||
int a;
|
||||
std::string b;
|
||||
};
|
||||
|
||||
py::class_<Aggregate>(m, "Aggregate")
|
||||
.def(py::init<int, const std::string &>());
|
||||
|
||||
.. note::
|
||||
|
||||
Note that brace initialization preferentially invokes constructor overloads
|
||||
taking a ``std::initializer_list``. In the rare event that this causes an
|
||||
issue, you can work around it by using ``py::init(...)`` with a lambda
|
||||
function that constructs the new object as desired.
|
||||
|
||||
.. _classes_with_non_public_destructors:
|
||||
|
||||
Non-public destructors
|
||||
|
@ -172,7 +172,7 @@ template <typename... Args> struct constructor {
|
||||
// we really can't support that in C++, so just ignore the second __init__.
|
||||
if (v_h.instance_registered()) return;
|
||||
|
||||
construct<Class>(v_h, new Cpp<Class>(std::forward<Args>(args)...), false);
|
||||
construct<Class>(v_h, new Cpp<Class>{std::forward<Args>(args)...}, false);
|
||||
}, extra...);
|
||||
}
|
||||
|
||||
@ -186,9 +186,9 @@ template <typename... Args> struct constructor {
|
||||
if (v_h.instance_registered()) return; // Ignore duplicate __init__ calls (see above)
|
||||
|
||||
if (Py_TYPE(v_h.inst) == cl_type->type)
|
||||
construct<Class>(v_h, new Cpp<Class>(std::forward<Args>(args)...), false);
|
||||
construct<Class>(v_h, new Cpp<Class>{std::forward<Args>(args)...}, false);
|
||||
else
|
||||
construct<Class>(v_h, new Alias<Class>(std::forward<Args>(args)...), true);
|
||||
construct<Class>(v_h, new Alias<Class>{std::forward<Args>(args)...}, true);
|
||||
}, extra...);
|
||||
}
|
||||
|
||||
@ -200,7 +200,7 @@ template <typename... Args> struct constructor {
|
||||
cl.def("__init__", [cl_type](handle self_, Args... args) {
|
||||
auto v_h = load_v_h(self_, cl_type);
|
||||
if (v_h.instance_registered()) return; // Ignore duplicate __init__ calls (see above)
|
||||
construct<Class>(v_h, new Alias<Class>(std::forward<Args>(args)...), true);
|
||||
construct<Class>(v_h, new Alias<Class>{std::forward<Args>(args)...}, true);
|
||||
}, extra...);
|
||||
}
|
||||
};
|
||||
@ -214,7 +214,7 @@ template <typename... Args> struct alias_constructor {
|
||||
cl.def("__init__", [cl_type](handle self_, Args... args) {
|
||||
auto v_h = load_v_h(self_, cl_type);
|
||||
if (v_h.instance_registered()) return; // Ignore duplicate __init__ calls (see above)
|
||||
construct<Class>(v_h, new Alias<Class>(std::forward<Args>(args)...), true);
|
||||
construct<Class>(v_h, new Alias<Class>{std::forward<Args>(args)...}, true);
|
||||
}, extra...);
|
||||
}
|
||||
};
|
||||
|
@ -280,6 +280,17 @@ TEST_SUBMODULE(class_, m) {
|
||||
#else
|
||||
.def("foo", static_cast<int (ProtectedB::*)() const>(&PublicistB::foo));
|
||||
#endif
|
||||
|
||||
// test_brace_initialization
|
||||
struct BraceInitialization {
|
||||
int field1;
|
||||
std::string field2;
|
||||
};
|
||||
|
||||
py::class_<BraceInitialization>(m, "BraceInitialization")
|
||||
.def(py::init<int, const std::string &>())
|
||||
.def_readwrite("field1", &BraceInitialization::field1)
|
||||
.def_readwrite("field2", &BraceInitialization::field2);
|
||||
}
|
||||
|
||||
template <int N> class BreaksBase { public: virtual ~BreaksBase() = default; };
|
||||
|
@ -195,3 +195,10 @@ def test_bind_protected_functions():
|
||||
|
||||
c = C()
|
||||
assert c.foo() == 0
|
||||
|
||||
|
||||
def test_brace_initialization():
|
||||
""" Tests that simple POD classes can be constructed using C++11 brace initialization """
|
||||
a = m.BraceInitialization(123, "test")
|
||||
assert a.field1 == 123
|
||||
assert a.field2 == "test"
|
||||
|
Loading…
Reference in New Issue
Block a user