In a C++ program, I have an API function with the following signature:
Foo const & GetFoo() const;
The Foo
class doesn’t allow copying or moving of instances. The API can’t easily be changed.
Now I want to write a function which gets passed the Foo
instance as one of its arguments – by reference, and as const
, since it is not going to be modified. For example:
void MyFunc(Bar someArg, Foo const & foo);
This works, but I am forced to pass a valid Foo
instance. I would like to make foo
optional, as I only need it in some cases.
Here’s what I’ve considered so far:
Foo*
) instead of a reference – works but not very elegant.Foo
and pass that whenever I don’t need the real deal – also not very elegant.MyFunc
with and without the foo
argument) – no easy way to do that without duplicating a lot of code, hence also not very elegant.std::optional
:
std::optional<Foo> const & foo
was my first attempt, which failed with invalid initialization of reference of type ‘const std::optional<Foo>&’ from expression of type ‘const Foo’
std::optional<Foo&>
is apparently not allowed in C++17 (or has that changed in C++20?), also: where would the const
part go?std::reference_wrapper
for such cases, but no easy-to-understand example of how to use it.So, how can I make the foo
argument in the above function optional? Is there any way to do that with std::optional
? If that involves std::reference_wrapper
, how would I use that?
This works:
#include <functional>
#include <optional>
void MyFunc(Bar someArg, std::optional<std::reference_wrapper<const Foo>> foo)
{
// ...
if (foo)
{
const Foo & realFoo = foo->get();
// do what you need if foo is set
}
// ...
}
When calling this function, pass std::cref(GetFoo())
or std::nullopt
, as needed.