Il giorno gio 29 lug 2021 alle ore 02:30 Barry Revzin via Std-Proposals <> ha scritto:

What would you do if value_at returned a T*? You can't do value_or() on a T*, because pointers have very few operations you can do on them (and nearly all of those would be straight up invalid in this use-case - which does not make for a great API!) you'd either push for some language feature that does that or you'd write some non-member function that handles this case. Which would be fine for value_or(), but not for any number of other operations that work for optional but not for pointers. What if you wanted the size of the span there, or 0?

With optional, these things just compose straightforwardly, so: m.value_at(p).transform(ranges::size).value_or(0)

How do you do that with a pointer? 

Note that neither of these examples work with optional<reference_wrapper<T>> either.

It seems to me you do need a pointer, because they carry an intrinsic "optionality" semantics with themselves, yet bare pointers lack the functionalities std::optional has, such as the value_or() method and possibly others. As already stated one can't have std::optional<T&> and std::optional<std::reference_wrapper<T>> is a substitute of it.

But I believe we can have the best of both worlds: we could wrap a pointer into a special type that std::optional would be specialized over, so that you can actually do things like 


As in the below example:

int main() {
    test_class test("hello");

    std::cout << test.value_at("hello").value_or("not found") << std::endl;
    std::cout << test.value_at("unexisting").value_or("not found") << std::endl;

    return 0;

Which would produce this output:

    not found

I've built a working example on godbolt. Have a look: