Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Modern C++ approach for providing optional arguments

Let's take the following function declaration:

void print(SomeType const* i);

Here, the const* nature of the argument i suggest the intent, that the parameter is optional, since it may be nullptr. If this was not intended, the argument would instead just be a const&. Communicating optional-semantics were certainly not the original intent for designing pointers, but using them to do so happens to work just fine for a long time.

Now, since using raw pointers is generally discouraged in modern C++ (and should be avoided in favor of std::unique_ptr and std::shared_ptr to precisely indicate particular ownership-semantics), I wonder how to properly indicate function parameters' optional-semantics without passing by value, i. e. copying, as

void print(std::optional<SomeType> i);

would do.

After thinking about it for a while I came up with the idea of using:

void print(std::optional<SomeType const&> i);

This would in fact be most precise. But it turns out that std::optional cannot have reference types.¹

Also, using

void print(std::optional<SomeType> const& i);

would in no way be optimal, since then we would require our SomeType to exists in an std::optional on the caller-side, again possibly (or rather likely) requiring a copy there.

Question: So what would be a nice modern approach for allowing optional arguments without copying? Is using a raw pointer here still a reasonable approach in modern C++?


¹: Ironically the depicted reason for why std::optional cannot have reference types (controversy about rebinding or forwarding on assignment) does not apply in the case of std::optionals of const references, since they cannot be assigned to.

like image 657
Reizo Avatar asked Oct 20 '20 10:10

Reizo


People also ask

How do you indicate optional arguments?

To indicate optional arguments, Square brackets are commonly used, and can also be used to group parameters that must be specified together. To indicate required arguments, Angled brackets are commonly used, following the same grouping conventions as square brackets.

Can you have optional parameters in C?

C does not support optional parameters.

What are optional function arguments?

Optional arguments enable you to omit arguments for some parameters. Both techniques can be used with methods, indexers, constructors, and delegates. When you use named and optional arguments, the arguments are evaluated in the order in which they appear in the argument list, not the parameter list.

What is optional in C function?

Optional arguments are generally not allowed in C (but they exist in C++ and in Ocaml, etc...). The only exception is variadic functions (like printf ).


4 Answers

Accepting a raw pointer is perfectly fine and is still done in plenty of "modern" codebases (which I'll note is a fast-moving target). Just put a comment on the function saying that it's allowed to be null and whether the function holds a copy of the pointer after the call (i.e. what are the lifetime requirements for the pointed-to value).

like image 101
John Zwinck Avatar answered Oct 19 '22 11:10

John Zwinck


Does function overloading provide a clean solution here? E.g. To declare both the const ref and empty param list versions of the function?
This may depend on what the function body does in the no argument/null case - and how you can manage the two implementations to minimize code overlap.

like image 37
Ricibob Avatar answered Oct 19 '22 11:10

Ricibob


Raw pointers are usually fine for this type of optional argument passing, actually one of the only times it is fine to use raw pointers overall. This is also the canonical recommended way.

That being said, boost::optional does allow you to use reference optional and const reference optionals. It was decided against to have this feature in the std library (for reasons I leave out here).

like image 5
darune Avatar answered Oct 19 '22 13:10

darune


This is actually what std::reference_wrapper was made for. Also see Does it make sense to combine optional with reference_wrapper? for more reasoning as to when to use it, and when not to use it.

like image 2
Daniël van den Berg Avatar answered Oct 19 '22 13:10

Daniël van den Berg