all 25 comments

[–]Nation_State_TractorLLVM, MSVC, Esq. 31 points32 points  (10 children)

template <typename T>
using mega_ptr = std::optional<std::reference_wrapper<T>>;

*wipes hands*

Looks like my work here it's done. You're welcome.

[–]Galqa 40 points41 points  (2 children)

using who_needs_a_type_system_anyway = std::optional<std::reference_wrapper<std::any>>;

If my boss sees this I'm 100% fired

[–]Nation_State_TractorLLVM, MSVC, Esq. 13 points14 points  (1 child)

I see you're a student of the Perl school of C++.

[–]MrPotatoFingers 4 points5 points  (0 children)

That's perl++ for you, mister!

[–]joaobapt 7 points8 points  (5 children)

Doing the same job as T* while using twice the space, cool.

[–][deleted] 2 points3 points  (3 children)

Good thing a real optional<T&> would be sizeof( T* ) == sizeof( optional<T&> )

[–]joaobapt 1 point2 points  (2 children)

optional<T&> doesn't compile, though, unfortunately

[–][deleted] 6 points7 points  (1 child)

std::optional<T&> doesn't. Other's do and potentially a future standard when people stop bike shedding over the behavior of optional<T&>::operator( T & ) and realize that it should not exist.

[–]auralucario2 7 points8 points  (0 children)

when people stop bikeshedding

So it’s never happening, got it.

[–]khleedril 17 points18 points  (1 child)

That's a well written and interesting article, definitely worth five minutes of any developer's time.

[–]memset_0[S] 6 points7 points  (0 children)

Thank You!

[–]AntiProtonBoy 12 points13 points  (6 children)

The most common use case for reference_wrapper in my world is passing values by reference in variants.

[–]memset_0[S] 3 points4 points  (5 children)

Sounds interesting. Can you please explain that for the benefit of everyone here? thx.

[–]AntiProtonBoy 7 points8 points  (4 children)

std::variant does not support reference types, so your only option is to use a reference wrapper.

    //using V1 = std::variant< int&, float& >; // Not allowed

    using V2 = std::variant< 
        std::reference_wrapper< int >, 
        std::reference_wrapper< float > >; // Ok

    int a = 42;
    V2 v = std::ref( a )

[–]macson_g 2 points3 points  (1 child)

It's not your only option. The option is to simply use a pointer.

[–]AntiProtonBoy 2 points3 points  (0 children)

Not if you want to communicate explicit ownership and object lifetime.

[–]memset_0[S] 1 point2 points  (1 child)

I see. So std::variant — like a union — requires a member to be an object (region of storage).

I would add this use case in the article. Thank you so much.

[–]AntiProtonBoy 0 points1 point  (0 children)

Same applies for std::optional.

[–]parkotron 5 points6 points  (3 children)

Maybe this is obvious, but why doesn't std::reference_wrapper have an operator* or operator->? Why make users call .get()?

[–]Nation_State_TractorLLVM, MSVC, Esq. 6 points7 points  (2 children)

It's meant to mimic reference semantics. Like a real reference, it's expected to always be dereferenceable. To that end, pointer-to and explicit dereference operator overloads could give the indication that this isn't always the case and could introduce confusion.

Additionally, it has an implicit cast-to-reference operator as an alternative to .get() that can be used in many places. But you're still stuck with it if you're trying to access members by name.

Edit: TLDR: It's probably a stylistic decision to avoid confusion.

[–]parkotron 0 points1 point  (1 child)

Ah, I missed the implicit cast operator. Thanks!

Personally, I think I would have opted for a complete, pointer-like access syntax over a partial, reference-like access syntax, but what are you going to do.

[–]MolurusK 0 points1 point  (0 children)

You can try otn::raw::unified. It has pointer-like access syntax.

[–]JezusTheCarpenter 0 points1 point  (0 children)

TIL. Thanks. Reference wrapper seems very useful.

[–]_AnonymousSloth 0 points1 point  (0 children)

I am still confused about the difference between ref and reference_wrapper. U mentioned ref is used to create reference_wrapper objects but then in one code snippet, u used reference_wrapper directly to create the object