0

Let's consider this code

std::optional<flat_set<int>> object;

void f(int v) {
    if (!object.has_value()) {
        object = flat_set<int>{};
    }
    object->insert(v);
}

How can I avoid if part? Is there any way to write the body of function in one line by calling one method?

Jarod42
  • 203,559
  • 14
  • 181
  • 302
Tigran Sahakyan
  • 363
  • 1
  • 5
  • 10
  • 1
    What is `std::optional::valid`? I guess you meant `objects->valid()`. If it is true, then this is not a question about optional. – YSC Feb 14 '19 at 12:21
  • Please provide a [mcve]. – YSC Feb 14 '19 at 12:24
  • I don't understand the point of this code. Even if we assume that `valid` was just `has_value`, this code clears the stored value if it exists, but does nothing if the optional is empty. Then it proceeds to straight up use the contained object. Like, the only reason to add the `if` in the first place is to make sure that you _keep_ UB if nothing is in optional yet. Analogous to "if you have an apple I'll replace it, otherwise you don't have an apple. Either way, now eat it." That's pretty pants-on-head. – Max Langhof Feb 14 '19 at 12:26
  • Edited to make sense. – Jarod42 Feb 14 '19 at 12:29
  • I would'nt move such a small bit of logic out. However you can reduce verbosity. `if(!object)object.emplace();` – balki Feb 14 '19 at 15:38

1 Answers1

4

There isn't much you can do to avoid the if unless you absolutely know that the optional has a value (and if you know, why use an optional?)

You could wrap the conditional part into a lambda/function:

#include <optional>
#include <boost/container/flat_set.hpp>

std::optional<boost::container::flat_set<int> > objects;

void f(int _v) 
{
    auto assure = [&]() -> decltype(auto)
    {
        if (objects.has_value())
            return *objects;
        else
            return objects.emplace();
    };

    assure().insert(_v);
}

another way...

#include <optional>
#include <boost/container/flat_set.hpp>

std::optional<boost::container::flat_set<int> > objects;

template<class T> 
auto assure_contents(std::optional<T>& opt) -> T&
{
    if (opt.has_value())
        return *opt;
    else
        return opt.emplace();
}

void f(int _v) 
{
    assure_contents(objects).insert(_v);
}
Richard Hodges
  • 68,278
  • 7
  • 90
  • 142