Skip to content

Use stricter brace initialization #1249

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Jan 12, 2018

Conversation

jagerman
Copy link
Member

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).

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 pybind#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).
@jagerman jagerman added this to the v2.2.2 milestone Jan 11, 2018
@jagerman
Copy link
Member Author

Cc @wjakob , @dean0x7d . I think this approach should restore the backwards-compatibility while still letting us have aggregate initializers, but I may be overlooking something.

@wjakob
Copy link
Member

wjakob commented Jan 11, 2018

The crazy corner cases that users of this project unearth don't cease to amaze. Your fix looks very reasonable to me!

@jagerman jagerman merged commit adbc811 into pybind:master Jan 12, 2018
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants