C++ Logo

std-proposals

Advanced search

Re: [std-proposals] Use optional<T> as though it were T

From: Edward Catmur <ecatmur_at_[hidden]>
Date: Sun, 25 Jun 2023 13:33:58 +0100
So you're checking on every access? That sounds like it's hiding a
potentially expensive operation. If we were to have a feature like that, it
feels like it would be worth generalising it to expression variables and,
ultimately, call by name.

On Sun, Jun 25, 2023, 12:53 Frederick Virchanza Gotham via Std-Proposals <
std-proposals_at_[hidden]> wrote:

> Let's say you started out writing a program with a global object:
>
> T g_obj;
>
> Now let's say that over 15 years, your program gets a lot bigger and
> so now you want to start conserving RAM. This global object has a
> constructor that allocates 100 megabytes of RAM, and so you decide to
> delay its construction until it's actually needed, so you change it
> to:
>
> optional<T> g_obj;
>
> Of course this would mean that you need to edit the code everywhere so
> that you have "g_obj->" instead of "g_obj.", unless of course you were
> to do:
>
> optional<T> g_optional_obj;
> T &g_obj = *g_optional_obj.operator->();
>
> Strictly speaking this is undefined behaviour but it will work fine so
> long as you make sure to 'emplace' the object before using 'g_obj'.
>
> But what if we could standardise a way of doing this that doesn't
> result in undefined behaviour? One possibility could be code that
> works something like as follows:
>
> #include <cassert> // cassert
> #include <optional> // optional, bad_optional_access
>
> using std::optional;
> using T = int;
>
> optional<T> g_optional_obj;
>
> #define NDEBUG // Try commenting this out
>
> #ifdef NDEBUG
> # define g_obj ( g_optional_obj.has_value() \
> ? g_optional_obj.value() \
> : throw std::bad_optional_access() )
> #else
> # define g_obj ( assert(g_optional_obj.has_value()), \
> g_optional_obj.value() )
> #endif
>
> // ============================== Here comes the test code:
>
> #include <iostream>
> using std::cout, std::endl;
>
> int main(void)
> {
> g_optional_obj.emplace(6);
> g_obj = 7;
> cout << g_obj << endl;
> }
>
> Try it up on GodBolt: https://godbolt.org/z/cz96bMW5j
>
> If we were to standardise a way of getting a "T&" from an
> "optional<T>&" at compile time, then the syntax could be something
> like as follows:
>
> std::optional<T> g_optional_obj -> g_obj;
>
> Or perhaps avoid a change to the syntax of the core language, and
> split it into two lines:
>
> std::optional<T> g_optional_obj;
> auto g_obj = g_optional_obj.compile_time_ref();
>
> Or another possible syntax:
>
> std::optional<T> g_optional_obj;
> auto g_obj = std::optional_compile_time_ref( g_optional_obj );
> --
> Std-Proposals mailing list
> Std-Proposals_at_[hidden]
> https://lists.isocpp.org/mailman/listinfo.cgi/std-proposals
>

Received on 2023-06-25 12:34:13