C++ Logo

std-proposals

Advanced search

Re: [std-proposals] std::elide

From: Arthur O'Dwyer <arthur.j.odwyer_at_[hidden]>
Date: Thu, 30 May 2024 11:35:30 -0400
On Thu, May 30, 2024 at 11:14 AM Frederick Virchanza Gotham via
Std-Proposals <std-proposals_at_[hidden]> wrote:

> On Thu, May 30, 2024 at 1:26 PM Gašper Ažman wrote:
> >
> > Both call a function to generate the returned type. Why
> > can't an elider *be that function* directly? That way I can
> > nest them either way and it still works.
>
> I have made the following two additions:
> template<typename NestedF, typename... NestedParams>
> constexpr decltype(auto) operator()(NestedF &&fN, NestedParams&&...
> argsN)
> {
> return forward<NestedF>(fN)( forward<NestedParams>(argsN)... );
> }
>

IIUC, this isn't right; what you want here is simply
// https://godbolt.org/z/7he9b6GW6

constexpr operator R()
noexcept(noexcept(apply(static_cast<F_ref>(f),std::move(args_tuple))))
{
return apply( static_cast<F_ref>(f), std::move(args_tuple) );
}

constexpr R operator()()
noexcept(noexcept(apply(static_cast<F_ref>(f),std::move(args_tuple))))
{
return *this;
}

as well as the const-qualified versions of those.
The idea, IIUC, is to make the following code work.
We suppose that the codebase already has their own `std::elide`-alike —
which, btw, isn't even a seven-liner; it's now a *five*-liner.

template<class F>
struct SCSE {
F f_;
operator decltype(f_())() const { return f_(); }
};

Then we have these two calls working already:

ocs8.emplace(std::elide([]{ return counting_semaphore<8>(5); }));
ocs8.emplace(SCSE([]{ return counting_semaphore<8>(5); }));

and Gasper is asking for this call to work as well:

ocs8.emplace(SCSE(std::elide([]{ return counting_semaphore<8>(5); }))); //
Gasper's request, IIUC

Adding the `operator()` gets us that. Although, I still don't see why we
want SCSE to be constructible from std::elide. I don't see how this helps
with "interop." What's a scenario where I'd already have a `std::elide`
object — whose sole purpose is to be treated like a `T` — and, instead of
treating it like a `T`, I'm going to try to construct an `SCSE` out of it?
That seems wrong. An `SCSE` expects a callable `C`, and so my `std::elide`
should implicitly convert to `C` iff `T=C`, but otherwise it should stay
aloof, IMHO. I don't see a concrete scenario where I'd want to be cavalier
about the meaning of `elide` — like, "Please convert to `T` if you can, or
otherwise convert to `SCSE`." Those are two different "parts of speech,"
IMO.

(But, just to be clear, I consider this all academic, because the STL *should
not have* `std::elide`.)

–Arthur

Received on 2024-05-30 15:35:47