C++ Logo

std-proposals

Advanced search

Re: [std-proposals] std::elide

From: Maciej Cencora <m.cencora_at_[hidden]>
Date: Wed, 22 May 2024 18:29:16 +0200
Here is a real-world problem:
Let's say you need to create a serialization framework with generic API
like:
template <typename T>
T deserialize();

It should support any user-defined aggregate types and with a single API
the framework should support two scenarios:
1) the usual deserialize into new object on stack
auto v = deserialize<T>();
2) deserialize directly into a preallocated specific region of memory
without blowing-up the stack on embedded systems for huge T
static T v;
...
new (&v) auto(deserialize<T>());

Thanks to guaranteed copy-ellision introduced in C++17 you can achieve
exactly that, with exceptions of arrays.
If T is a struct containing C-style array then you cannot create
deserialize specialization that uses RVO:
struct Foo { int a[1]; }

template <>
Foo deserialize()
{
    return { .a = deserialize<int[1]>() };
}

This won't compile as C-style arrays cannot be returned from function by
value.

You could workaround it by expanding the array initialization with a help
of std::index_sequence, like:
template <std::size_t ...Ints>
Foo deserialize(std::index_sequence<Ints...>)
{
    return { .a = { (Ints, deserialize<int>())... } };
}
But this is impossible if T has multiple arrays, or if arrays size is big
(you hit template instantiations limit on your compiler, and what is worse
the compilers don't fold this back into a loop so your binary gets huge).

You may say don't use C-style arrays, but the decision may not be up to
you.
And even if you force std::array you get hit by the template instantiations
limit and binary bloat anyway.

With NRVO you could have it all.

Regards,
Maciej Cencora






śr., 22 maj 2024 o 17:00 Tiago Freire via Std-Proposals <
std-proposals_at_[hidden]> napisał(a):

> As mentioned before, it is not enough to have a theoretical discussion,
> you need a practical reason to justify adding a new feature.
> You have to consider alternative ways to do what you are trying to do, and
> then justify why your approach is better.
> And what has been displayed was a convoluted amount of code to try and
> write something that shouldn't been written, and whose alternative is a
> single line of code.
>
> The argument is not convincing, and you need to convince me that other
> objects that are also not movable don't have the exact same issues,
> justifying why you need to enforce RVO instead of passing in a reference.
> Get an example that actually needs it, then we have a point of discussion,
> until then it is not solving a problem.
> I hope I made my point clear.
>
>
> -----Original Message-----
> From: Std-Proposals <std-proposals-bounces_at_[hidden]> On Behalf Of
> Frederick Virchanza Gotham via Std-Proposals
> Sent: Wednesday, May 22, 2024 16:37
> To: std-proposals_at_[hidden]
> Cc: Frederick Virchanza Gotham <cauldwell.thomas_at_[hidden]>
> Subject: Re: [std-proposals] std::elide
>
> On Wed, May 22, 2024 at 2:17 PM Tiago Freire wrote:
> >
> > While I can understand RVO, mutexes has got to be the worst possible
> > example for an application of this.
>
>
> Let's say it's Summer time and I'm out the back garden at my house on a
> sunny day, and I'm trying out my brand new fruit blender. Tiago, you come
> over to my house and I've already made my smoothie, but there's still one
> pineapple sitting on the table, and even though a pineapple isn't a great
> choice of fruit for blending, it's right there right now and so I just grab
> it and throw it in the blender to show off my new blending skills. I could
> have stood up and walked into my house to the kitchen to grab a softer
> piece of fruit but I'm just not bothered -- the pineapple is there and it
> will do.
>
> We've been consistently using "std::mutex" because it's right there right
> now. We just need to write "#include<mutex>" and we have an
> unmovable-and-uncopyable type. That's literally the only reason we're all
> talking about mutexes in this thread. It's easier to write those
> 15 characters, "#include<mutex>", than to go to the bother of typing
> out:
>
> struct S {
> MyClass(MyClass const &) = delete;
> MyClass(MyClass &&) = delete;
> int n;
> };
>
> You seem to be very technically-minded Tiago and perhaps that's why you
> drill further into the logic than the rest of us here. Sometimes though, we
> just want a quick-and-easy example to demonstrate an idea we're working on
> -- and sometimes we don't give much consideration to how sensible our
> quick-and-easy example is. The world would probably be a better place if we
> were all as analytically-prone as you Tiago, but for the time being we just
> want to write out short little simple code snippets.
> --
> Std-Proposals mailing list
> Std-Proposals_at_[hidden]
> https://lists.isocpp.org/mailman/listinfo.cgi/std-proposals
> --
> Std-Proposals mailing list
> Std-Proposals_at_[hidden]
> https://lists.isocpp.org/mailman/listinfo.cgi/std-proposals
>

Received on 2024-05-22 16:29:31