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.