Skip to content
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

Revert noexcept deduction in favour of SFINAE lambda function matching #677

Merged
merged 1 commit into from
Feb 17, 2017

Conversation

jagerman
Copy link
Member

noexcept deduction, added in PR #555, doesn't work with clang's -std=c++1z; and while it works with g++, it isn't entirely clear to me that it is required to work in C++17.

What should work, however, is C++17's umplicit conversion of a noexcept(true) function pointer to a noexcept(false) one (i.e. default, noexcept-specifier-omitted). That was breaking in C++17 mode in pybind11 before #555 because the cpp_function template used for lambdas provided a better match (i.e. without requiring an implicit conversion), but it then failed when trying to treat the matched function pointer as a lambda object.

This commit takes a different approach of using SFINAE on the lambda function to prevent it from matching a non-lambda object, which then gets implicit conversion from a noexcept function pointer to a noexcept(false) function pointer. This much nicer solution also gets rid of the C++17 NOEXCEPT macros, and works in both clang and g++.

With this, pybind11 builds and tests successfully with clang 4.0 and libc++ 4.0 on linux under -std=c++1z.

noexcept deduction, added in PR pybind#555, doesn't work with clang's
-std=c++1z; and while it works with g++, it isn't entirely clear to me
that it is required to work in C++17.

What should work, however, is that C++17 allows implicit conversion of a
`noexcept(true)` function pointer to a `noexcept(false)` (i.e.  default,
noexcept-not-specified) function pointer.  That was breaking in pybind11
because the cpp_function template used for lambdas provided a better
match (i.e. without requiring an implicit conversion), but it then
failed.

This commit takes a different approach of using SFINAE on the lambda
function to prevent it from matching a non-lambda object, which then
gets implicit conversion from a `noexcept` function pointer to a
`noexcept(false)` function pointer.  This much nicer solution also gets
rid of the C++17 NOEXCEPT macros, and works in both clang and g++.
@wjakob
Copy link
Member

wjakob commented Feb 17, 2017

That's a much nicer solution, and it makes this quite readable again -- thank you!

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.

None yet

2 participants