I'm having trouble understanding this thread. I still can't figure out the answer to this question: does "Mandates:" allow defining a function as deleted, or not?

Obviously, deleting a function is different from "Constraints". It's also different from putting a static assertion in the body, because if you test the validity of the call in an unevaluated context, e.g. using a requires-expression, then in the deleted case, you see that it's not valid, while in the case of a static assertion in the body, you see that it is valid, but then get a hard error if you retry the same call in an evaluated context.

The impression I've been given at another point in time was that "Mandates:" is supposed to mean the latter behavior, but the library wording doesn't outright say that, because we're not sure whether every existing use of "Mandates:" is consistent with that. But, in the meantime, I don't see the value of having a note that goes against the intent.

On Tue, Mar 24, 2026 at 3:23 AM Jonathan Wakely via Std-Proposals <std-proposals@lists.isocpp.org> wrote:


On Tue, 24 Mar 2026, 02:03 Jonathan Wakely, <cxx@kayari.org> wrote:


On Tue, 24 Mar 2026, 01:52 Jonathan Wakely, <cxx@kayari.org> wrote:


On Tue, 24 Mar 2026, 01:19 Halalaluyafail3, <luigighiron@gmail.com> wrote:
On Mon, Mar 23, 2026 at 9:06 PM Jonathan Wakely <cxx@kayari.org> wrote:
>
>
>
> On Tue, 24 Mar 2026, 00:34 Halalaluyafail3 via Std-Proposals, <std-proposals@lists.isocpp.org> wrote:
>>
>> N5032 Section 16.3.2.4 "Detailed specifications" [structure.specifications]
>> Paragraph 3:
>> > Mandates: the conditions that, if not met, render the program ill-formed.
>>
>> Consider the following program:
>>
>> #include<bit>
>> decltype(std::bit_cast<void*>(^^::))x;
>>
>> Assume sizeof(void*)==sizeof(^^::) is true. Is this program ill-formed? It would
>> seem that is the case, but existing implementations do not reject this.
>
>
> You haven't instantiated the function template. The return type is clearly void* so checking it without odr-using the function might works, but is kinda dumb.
>
> In an uninstantiated template the condition is not necessarily checked.

I do not see how the current wording supports such an interpretation. Note that
std::declval is specified using the mandate "This function is not odr-used", is
this redundant and could be reduced to "false is true" similar to the
preconditions of std::unreachable?

Do you really think trying to draw general conditions from the wording for those two findings makes sense? 

Those tell functions cannot be evaluated ever in a valid program. There are no specializations of declval that are usable, ever. And any call to unreachable is a bug.

Maybe they're special cases, which are not good examples of general purpose wording. 

If there's a defect here, it's that declval tries to use library specification wording to say "this is only valid in unscented contexts"

Thanks autocorrect. 

They should say "unevaluated contexts".


and we should have a special case in core wording just for this function. But it didn't seem worth doing. We know what the spec means, and no implementation has ever tried to implement declval as a deleted function. That wouldn't work (and the spec doesn't say that an implementation must pick *either* static assert *or* deleted functions, and use that consistently for every Mandates).

But that's ok because declval is a very weird special case. 

And unreachable is another weird special case, where wording that is suitable for other functions is used a little strangely because we don't have a good way to say "this is always a bug if evaluated".

But that's not a general problem with the spec for Mandates.








>
>> The
>> example that follows the quoted text suggests that two possible implementations
>> of mandates are static_asserts and deleted overloads. For uses of mandates
>> outside of templates it seems like deleting the function is the only way to
>> implement the mandate.
>
>
> Why?

Since a static_assert failing there would immediately make the program
ill-formed. The only way to delay that until its use would be =delete.

>
>> For uses of mandates inside of templates both options
>> would be valid, and create differences in the validity of programs such the
>> program above. Was it intended for both possibilities to be valid, or was it
>> intended for this program to assuredly be ill-formed or well-formed?
>
>
> I don't think it matters. If it mattered and the condition was supposed to be SFINAE testable, it would use Constraints not Mandates.
>
> Why would you ever need the code above to be portable?

Not to say that requiring this would be useful, but it seems like intent is not
currently reflected in how Mandates is specified.

>
>
>>
>> It seems like the uses of Mandates for the purposes of specifying deletion could
>> be split up into a new "Deleted When" element, if the intent was to require one
>> form be used. For example text_encoding uses mandates to require CHAR_BIT==8,
>> that could realistically only be implemented as a deleted overload. Would it
>> make sense to open a LWG issue for this?
>
>
> I don't see a defect here.
>
>
>
--
Std-Proposals mailing list
Std-Proposals@lists.isocpp.org
https://lists.isocpp.org/mailman/listinfo.cgi/std-proposals


--
Brian Bi