Date: Thu, 16 Apr 2026 20:02:57 -0400
On Thu, Apr 16, 2026 at 4:45 PM Adrian via Std-Proposals
<std-proposals_at_[hidden]> wrote:
>
> i have this template
>
> ```cc
>
> template <typename T, typename... OptionalArgs>
> concept HandlerController =
> requires(T a, std::uint32_t id) {
> { a.schedule(id) } -> std::same_as<void>;
> { a.deschedule(id) } -> std::same_as<void>;
> { a.release(id) } -> std::same_as<void>;
> } && requires(T a, shared::WorkerFunction work,
> shared::ReleaseFunction release, shared::ErrorHandler error,
> OptionalArgs... opt_args) {
> { a.create(work, release, error, opt_args...) } -> HandlerTemplate;
> };
>
> class Example {};
>
> ```
>
> i want to enforce this behavior on a class. Even if the class is unused,
> etc... so for that the only possible option right now is to
> use static_assert(HandlerController<Example>). I thought how about just
> writing:
>
> ```cc
>
> class Example
>
> requires(HandlerController<Example>)
>
> {};
So, in this hypothetical, you are writing `Example`. That is, it's not
someone else's type that you're trying to verify fulfills some
concept. It's your class that you want to ensure fulfills a concept.
The reason I bring this up is that, outside of personal preference,
the only functional difference between your proposed
`requires(HandlerController<Example>)` and using
`static_assert(HandlerController<Example>)` is that the former
attaches the concept check to the class definition, while the latter
does not. Ignoring questions of implementability (the declarations
that `requires` would have to check haven't been written yet, so it
would have to actually defer checking the concept until later),
putting it in the class definition creates (at least) two usability
problems:
1. You may well want to do this to a class you *don't* control. That
is, some library wrote a class and you want to make sure that it
fulfills a concept. And `static_assert` is the only way to do that. So
now you have two mechanisms for saying the same conceptual thing, and
which one you use depends entirely on whether you have control of a
class. This seems unnecessary.
2. What if you want to do this to a concept that has any
non-class-member interfaces? That is, there are free functions which
this concept uses, but those free functions aren't declared before the
class definition. So again, you're forced to use `static_assert`.
It seems to me that the `static_assert` method is functionally
superior. Not only does the `requires` clause give you no power that
`static_assert` can't provide, it also limits the kinds of concepts
you can even check.
<std-proposals_at_[hidden]> wrote:
>
> i have this template
>
> ```cc
>
> template <typename T, typename... OptionalArgs>
> concept HandlerController =
> requires(T a, std::uint32_t id) {
> { a.schedule(id) } -> std::same_as<void>;
> { a.deschedule(id) } -> std::same_as<void>;
> { a.release(id) } -> std::same_as<void>;
> } && requires(T a, shared::WorkerFunction work,
> shared::ReleaseFunction release, shared::ErrorHandler error,
> OptionalArgs... opt_args) {
> { a.create(work, release, error, opt_args...) } -> HandlerTemplate;
> };
>
> class Example {};
>
> ```
>
> i want to enforce this behavior on a class. Even if the class is unused,
> etc... so for that the only possible option right now is to
> use static_assert(HandlerController<Example>). I thought how about just
> writing:
>
> ```cc
>
> class Example
>
> requires(HandlerController<Example>)
>
> {};
So, in this hypothetical, you are writing `Example`. That is, it's not
someone else's type that you're trying to verify fulfills some
concept. It's your class that you want to ensure fulfills a concept.
The reason I bring this up is that, outside of personal preference,
the only functional difference between your proposed
`requires(HandlerController<Example>)` and using
`static_assert(HandlerController<Example>)` is that the former
attaches the concept check to the class definition, while the latter
does not. Ignoring questions of implementability (the declarations
that `requires` would have to check haven't been written yet, so it
would have to actually defer checking the concept until later),
putting it in the class definition creates (at least) two usability
problems:
1. You may well want to do this to a class you *don't* control. That
is, some library wrote a class and you want to make sure that it
fulfills a concept. And `static_assert` is the only way to do that. So
now you have two mechanisms for saying the same conceptual thing, and
which one you use depends entirely on whether you have control of a
class. This seems unnecessary.
2. What if you want to do this to a concept that has any
non-class-member interfaces? That is, there are free functions which
this concept uses, but those free functions aren't declared before the
class definition. So again, you're forced to use `static_assert`.
It seems to me that the `static_assert` method is functionally
superior. Not only does the `requires` clause give you no power that
`static_assert` can't provide, it also limits the kinds of concepts
you can even check.
Received on 2026-04-17 00:03:11
