It's a long article; I read most of it, but skimmed some of it quickly toward the end.
Thanks for pointing that out; see the "§ What about optional_ref<T>?" just before the conclusion (same name and all).
I probably missed it because it has no code box; if I get tired of reading something long, I start to gravitate toward code rather than walls of text.
optional_ref being "spelled differently" is a given. It has different semantics from optional, and doesn't replace it (as is noted) and so of course it deserves a different name. An optional reference to something (which itself isn't optional) isn't the same as an optional something (which either exists or doesn't). This is a fluff objection.
Regarding the objection against duplicating code in the implementation for things like map:
1. So what? C++ is full of duplication.
2. All the same, perhaps the implementor could find a way to share some implementation bits between optional and optional_ref. I haven't tried a cut at it, but it doesn't seem self-evident to me that the only way to implement optional_ref is complete copy and paste from optional.
The author has a valid points about there being issues with having to hard code either optional or optional_ref in places in the user code.
Maybe a combind super_optional<bool ref, T> which goes to optional<T> if ref is false otherwise to optional_ref<T> could help.
That is similar in spirit to the workaround, except the choice of "ref or not" isn't extracted from a T& versus T argument; it's an explicit template parameter.
In the end the author's conclusion is indeed that "optional_ref<T> is a much better optional reference than T*, but it’s still a poor substitute", where by substitute I think he means "alternative for the nonexistent optional<T&>".
#include <optional>
#include <functional>
#include <type_traits>
using std::optional;
using std::conditional_t;
using std::reference_wrapper;
using std::cout;
using std::endl;
template <typename T>
class optref {
T *ptr;
public:
optref<T>() : ptr(nullptr) { }
optref<T>(T &obj) : ptr(&obj) { }
optref<T> &operator =(const T &rhs)
{
if (!ptr)
throw 42;
*ptr = rhs;
return *this;
}
};
template <bool ref, typename T>
using opt = conditional_t<ref, optref<T>, optional<T>>;
int main()
{
int x = 42;
opt<true, int> rox = x;
rox = 3;
cout << x << endl;
}
Compiles with GNU g++ -std=c++17 -Wall -W -pedantic.
The output is
3
showing that rox is a reference to x. Via the hacky assignment operator I threw in for this purpose.
We can build abstractions on opt<ref, T> but they have to carry that pesky parameter. If we can move it to the right and default it to false, that helps if most of our optionals aren't references.
Thanks for pointing that out; see the "§ What about optional_ref<T>?" just before the conclusion (same name and all).
I probably missed it because it has no code box; if I get tired of reading something long, I start to gravitate toward code rather than walls of text.
optional_ref being "spelled differently" is a given. It has different semantics from optional, and doesn't replace it (as is noted) and so of course it deserves a different name. An optional reference to something (which itself isn't optional) isn't the same as an optional something (which either exists or doesn't). This is a fluff objection.
Regarding the objection against duplicating code in the implementation for things like map:
1. So what? C++ is full of duplication.
2. All the same, perhaps the implementor could find a way to share some implementation bits between optional and optional_ref. I haven't tried a cut at it, but it doesn't seem self-evident to me that the only way to implement optional_ref is complete copy and paste from optional.
The author has a valid points about there being issues with having to hard code either optional or optional_ref in places in the user code.
Maybe a combind super_optional<bool ref, T> which goes to optional<T> if ref is false otherwise to optional_ref<T> could help.
That is similar in spirit to the workaround, except the choice of "ref or not" isn't extracted from a T& versus T argument; it's an explicit template parameter.
In the end the author's conclusion is indeed that "optional_ref<T> is a much better optional reference than T*, but it’s still a poor substitute", where by substitute I think he means "alternative for the nonexistent optional<T&>".