Date: Sun, 24 Oct 2021 22:54:41 +0100
On Sun, 24 Oct 2021 at 21:28, Thiago Macieira via Std-Proposals <
std-proposals_at_[hidden]> wrote:
> Anyway, considering the other posters' solutions to check that the object
> is
> constexpr-constructible, I would feel better if there way a blessed,
> standardised way to spell it, instead of everyone rolling out their comma
> operator expressions.
>
It's a bit tricky. The problem is that for full generality, you want to
deal with expressions where the inputs and/or outputs may be
non-structural, so can't be passed by template even when they are constant
expressions.
That means that if you make your library facility something like:
template<auto> struct constant_value_t {};
template<auto A> inline constexpr constant_value_t<A> constant_value;
you still need to use a comma on its operand:
if constexpr (requires { constant_value<(t.h(n), void(), 0)>; }) {
Here t and n are constant expressions, of course.
And if conversely you encapsulate the comma in a facility:
template<auto F, auto... A> concept constant_invocable =
requires { constant_value<(F(A...), void(), 0)>; };
the user now has the overhead of writing a non-capturing lambda, passing
the arguments in, and it won't work for non-structural argument types:
if constexpr (constant_invocable<[](T t) { t.h(n); }, t>) {
Quick demo: https://godbolt.org/z/44GKTPv5z
So the library facility here helps somewhat, but it's not much of a win
over using bool_constant or simply a lambda with template argument:
if constexpr (requires { []<auto>().template operator()<(t.h(n), void
(), 0)>(); }) {
This is probably an argument for a language level facility (constexpr as
predicate?), but well - is there enough pain here to justify it?
std-proposals_at_[hidden]> wrote:
> Anyway, considering the other posters' solutions to check that the object
> is
> constexpr-constructible, I would feel better if there way a blessed,
> standardised way to spell it, instead of everyone rolling out their comma
> operator expressions.
>
It's a bit tricky. The problem is that for full generality, you want to
deal with expressions where the inputs and/or outputs may be
non-structural, so can't be passed by template even when they are constant
expressions.
That means that if you make your library facility something like:
template<auto> struct constant_value_t {};
template<auto A> inline constexpr constant_value_t<A> constant_value;
you still need to use a comma on its operand:
if constexpr (requires { constant_value<(t.h(n), void(), 0)>; }) {
Here t and n are constant expressions, of course.
And if conversely you encapsulate the comma in a facility:
template<auto F, auto... A> concept constant_invocable =
requires { constant_value<(F(A...), void(), 0)>; };
the user now has the overhead of writing a non-capturing lambda, passing
the arguments in, and it won't work for non-structural argument types:
if constexpr (constant_invocable<[](T t) { t.h(n); }, t>) {
Quick demo: https://godbolt.org/z/44GKTPv5z
So the library facility here helps somewhat, but it's not much of a win
over using bool_constant or simply a lambda with template argument:
if constexpr (requires { []<auto>().template operator()<(t.h(n), void
(), 0)>(); }) {
This is probably an argument for a language level facility (constexpr as
predicate?), but well - is there enough pain here to justify it?
Received on 2021-10-24 16:54:54