C++ Logo

std-proposals

Advanced search

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

From: Breno Guimarães <brenorg_at_[hidden]>
Date: Tue, 27 Jun 2023 21:05:43 -0300
You can do:

T& g_obj_fn() {
    static T t;
    return t;
}

#define g_obj (g_obj_fn())

Function local statics do the flag+muted+call_once for you.



Em ter., 27 de jun. de 2023 20:47, Frederick Virchanza Gotham via
Std-Proposals <std-proposals_at_[hidden]> escreveu:

> I think the most efficient implementation of a "construct on demand"
> object would work as follows:
>
> https://godbolt.org/z/dx6YTKnnj
>
> And here it is copy-pasted:
>
> #include <atomic> // atomic
> #include <optional> // optional
> #include <mutex> // once_flag, call_once, mutex,
> lock_guard
> #include <iostream> // Just for testing: 'cout'
> #include <thread> // Just for testing: 'jthread'
>
> struct T {
> T(void) { std::cout << "Constructing. . .\n"; }
> ~T(void) { std::cout << "Destroying. . .\n" ; }
> void Speak(void) { std::cout << "Hi!\n"; }
> };
>
> std::optional<T> g_optional;
>
> /* forward declaration of function */ T &Func_PreInit(void);
>
> std::atomic<T &(*)(void)> g_funcptr{ &Func_PreInit };
>
> static std::mutex g_mutex_for_optional;
>
> T &Func_Init(void)
> {
> std::cout << "> > > Func_Init\n";
>
> std::lock_guard mylock(g_mutex_for_optional);
>
> return g_optional.value();
> }
>
> std::once_flag g_flag_for_optional{};
>
> T &Func_PreInit(void)
> {
> std::cout << "> > > Func_PreInit\n";
>
> std::call_once(g_flag_for_optional, []()
> {
> std::lock_guard mylock(g_mutex_for_optional);
> g_optional.emplace();
> });
>
> g_funcptr.store( &Func_Init );
>
> std::lock_guard mylock(g_mutex_for_optional);
> return g_optional.value();
> }
>
> #define g_obj (g_funcptr.load()())
>
> int main(void)
> {
> g_obj.Speak();
> std::jthread mythread( [](){ g_obj.Speak(); } );
> g_obj.Speak();
> }
> --
> Std-Proposals mailing list
> Std-Proposals_at_[hidden]
> https://lists.isocpp.org/mailman/listinfo.cgi/std-proposals
>

Received on 2023-06-28 00:05:56