1

Here is an example in my code, using std::optional:

Max = index(summary_max.value(), clusters[summary_max.value()]->Maximum().value());

Here, summary_max and Maximum() is std::optional. This is WAY verbose. I want to type just index(summary_max, clusters[summary_max]->Maximum());

Why doesn't std::optional<T> support implicit casting to T? Is there any valid, inevitable rationale?

frozenca
  • 839
  • 4
  • 14

2 Answers2

5

If you are certain your optional objects does indeed have values, you could use the operator* operator function instead of the value() member function:

Max = index(*summary_max, 
            *(clusters[*summary_max]->Maximum()));
// rant: looks more like C than C++ to me.

But as you are using the stored valued of summary_max twice, you may simply want to extract (copy/const ref) prior to using it in index(...) invocation.

const auto& max_index = summary_max.value();
Max = index(max_index, *(clusters[max_index]->Maximum()));
dfrib
  • 70,367
  • 12
  • 127
  • 192
4

Why doesn't std::optional support implicit [conversion] to T? Is there any valid, inevitable rationale?

It can't! The presence of the T is optional. If there isn't one set, what should an implicit conversion do? Produce a default-constructed T? That's not even always possible.

The library therefore makes you decide what should happen, and this can be done either with value() or by simply dereferencing (if you're sure there is a value).

But there's no need for this technique to be terribly verbose:

const auto& val         = summary_max.value();
const auto& cluster_max = clusters[val]->Maximum().value();

Max = index(val, cluster_max);

As an aside, "casting" means "explicit conversion", so there's no such thing as an "implicit cast". ;)

Asteroids With Wings
  • 17,071
  • 2
  • 21
  • 35