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

Using constraints for Mandates: conditions changes the overload set #41

Open
jwakely opened this issue Jul 18, 2024 · 2 comments
Open
Assignees

Comments

@jwakely
Copy link

jwakely commented Jul 18, 2024

https://github.com/beman-project/Optional26/blob/bfeb9080c0d9c501965ae857a1decf7ed74686f5/include/Beman/Optional26/optional.hpp#L487-L499

Unless you're really sure it doesn't change semantics, the correct way to implement Mandates: requirements is with a static_assert or other non-SFINAE-able check outside the immediate context.

Using constraints on overloaded functions means that the correct overload might be removed from the overload candidates, and another function gets called. That fails to conform to the requirement that Mandates: makes a program ill-formed.

For example, give a type that is copy constructible but not move constructible, calling std::optional<T>{}.value_or(t) should be ill-formed, because the value_or(U&&) && overload says:

Mandates: is_move_constructible_v<T> && is_convertible_v<U&&, T> is true.

But the way you've implemented it, that overload will not be called because its constraints are not satisfied, so the value_or(U&&) const & overload will get called instead. Calling a different function is not a valid way to implement "ill-formed".

@steve-downey steve-downey self-assigned this Jul 18, 2024
@steve-downey
Copy link
Member

Almost certainly me misreading the spec when I went through applying parts.

One of the reasons I now have a stronger preference towards having requires expressions in the synopsis, so I don't accidentally confuse the two.

I still wish that Contraints that are really truely a static_assert would just have the expression rather than possibly saying that the expression above has value \tcode{true}, or worse \tcode{false}.

https://github.com/cplusplus/draft/blob/motions-2024-06-lwg-12/source/exec.tex#L879-L881

@jwakely
Copy link
Author

jwakely commented Jul 18, 2024

rather than possibly saying that the expression above has value \tcode{true}, or worse \tcode{false}.

That's not what the linked example is saying. It's saying that iff the expression above is well-formed, then the type of that expression is required to satisfy scheduler. If the expression above is not well-formed, we can't require it to satisfy anything. We can only impose a requirement on what get_scheduler(env) does if the query is well-formed in the first place.

As a static assert that would be static_assert( scheduler<decltype((repeat that big expression))> ) in the function body of the CPO's operator().

@steve-downey steve-downey mentioned this issue Jul 22, 2024
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

No branches or pull requests

2 participants