Use stricter brace initialization
This updates the `py::init` constructors to only use brace
initialization for aggregate initiailization if there is no constructor
with the given arguments.
This, in particular, fixes the regression in #1247 where the presence of
a `std::initializer_list<T>` constructor started being invoked for
constructor invocations in 2.2 even when there was a specific
constructor of the desired type.
The added test case demonstrates: without this change, it fails to
compile because the `.def(py::init<std::vector<int>>())` constructor
tries to invoke the `T(std::initializer_list<std::vector<int>>)`
constructor rather than the `T(std::vector<int>)` constructor.
By only using `new T{...}`-style construction when a `T(...)`
constructor doesn't exist, we should bypass this by while still allowing
`py::init<...>` to be used for aggregate type initialization (since such
types, by definition, don't have a user-declared constructor).
diff --git a/tests/test_class.py b/tests/test_class.py
index d94b61b..8cf4757 100644
--- a/tests/test_class.py
+++ b/tests/test_class.py
@@ -228,6 +228,12 @@
assert a.field1 == 123
assert a.field2 == "test"
+ # Tests that a non-simple class doesn't get brace initialization (if the
+ # class defines an initializer_list constructor, in particular, it would
+ # win over the expected constructor).
+ b = m.NoBraceInitialization([123, 456])
+ assert b.vec == [123, 456]
+
@pytest.unsupported_on_pypy
def test_class_refcount():