However, a reference_wrapper is perfectly copyable, so it's value can always be changed, so why preventing it to have the null reference by default?
What would be the point of std::reference_wrapper
to have a null value? If you need to have a null value, just use a pointer :P
std::reference_wrapper
is built as a wrapper to a reference, that's it. It must behave like a reference would, or else it wouldn't be a wrapper but something else. There are use-cases for it, which would possibly break if you allow a default value for it. If you need to have a null value, either use something else, like a pointer, or live with the limitations of references.
Also, you state a reason yourself:
[...] even though using a default constructed reference_wrapper causes a runtime exception.
What's the point in having a reference to nothing? Having a std::reference_wrapper
implies that it refers to something, just like a reference would. Adding a null value would just mean additional code every time the reference is used to see if it is null or not.
It makes many usage cases much simpler [...]
Yes, maybe. But it'll make other use-cases much harder. You'll need to check if the wrapper is valid or not, don't forget to initialize it when used as a member with a default constructor, and more.
In short, std::reference_wrapper
is just a wrapper to a reference, and as such cannot behave as something else than just a plain reference. Everything has an advantage and a disadvantage, here, you might need std::observer_ptr
, but in other cases, you don't need to do any checks.
std::array
of reference_wrappers is pure pain. In addition to the default constructor, however, one would further need an assignment operator taking the wrapped references. – Fortnightlystd::array
of a non-default-constructible type as painful; you either just specify the elements in the initialiser, or you write a not-too-difficult (and better since C++14) helper function that recursively generates the elements using a lambda (passing the index, in the case of my own helper for this). Also, if this is what you meant,reference-wrapper
already does haveoperator=(reference_wrapper)
that rebinds from the RHS. If you instead meant you would want assignment to assign between the referred objects instead, that'd totally break containers. – Frillstd::reference_wrapper
with an empty state, just put it inside anstd::optional
. – Frillstd::optional
, that makes it better indeed. – Fortnightly