Is there a way of using `std::optional` optionally for all the members in a class

Viewed 94

Consider the classes

struct Foo1
{
    int n;
    double m;   
};

and

struct Foo2
{
    std::optional<int> n;
    std::optional<double> m;    
};

In reality the number of members is greater than this. Is there a way I can templatise this to one class, something like

template<class T>
struct Foo
{
    T<int> n;
    T<double> m;
};

where if T is std::optional then Foo is the same as Foo2, and if T is "nothing at all" then it's the same as Foo1. They don't have to be formally the same, just have the same member types if you get my meaning.

So then I could write Foo<std::optional> foo2; in order to make all the members optional or Foo<whatever> foo1; to make them not optional.

I'm using C++14, although if this requires techniques beyond that standard, I'll live with it!

1 Answers

You can write a simple switch that chooses between a type or its optional:

template <typename T, bool O = false>
using optionally_optional = std::conditional_t<O, std::optional<T>, T>;

And then, use it as follows:

template <bool O>
struct Foo
{
    optionally_optional<int, O> n;
    optionally_optional<double, O> m;
};
Related