1

Is there a way to only use some optional arguments of a function? So if I have a function like this,

void f(int a = 0, int b = 1) {}

can I call f() and only specify b and leave a on its default value?

user11914177
  • 677
  • 3
  • 21

1 Answers1

6

I wish. C++ lacks this feature that is common in other languages (like C# or Python).

For now, you are stuck with either being very clever about designing the order of your parameters, or refactoring your parameters into a small struct:

struct f_args
{
   int a = 0;
   int b = 1;
};

Now you can optionally set whatever you want:

void f(f_args args){/*...*/};

// ...
f_args args;
args.b = 2;
f(args);

Or with designated initializers (C++20):

f({.b=2});

The Boost parameter library attempts to tackle this problem in a more robust way.

AndyG
  • 35,661
  • 8
  • 94
  • 126
  • Thanks, this looks like an alright workaround – user11914177 May 12 '21 at 19:52
  • @user11914177: It is also pretty much the way the Vulkan API decided to go for its API. The good part about this is that it's very robust to reordering or adding new arguments. Additionally, now that you have a class, you can take this pattern to advanced levels by creating e.g., fluent interface for `f_args` to set the parameters that you want, or push the creation of the parameters into a builder pattern that eventually produces the appropriate `f_args` object. – AndyG May 12 '21 at 19:54
  • I never got the point of the [named parameter idiom](https://isocpp.org/wiki/faq/ctors#named-parameter-idiom) suggested elsewhere, "naming the parameters" like this is much simpler and cleaner imho. – 463035818_is_not_a_number May 12 '21 at 19:55
  • 1
    @largest_prime_is_463035818: This way can get annoying especially for really obvious functions (e.g., addition, you don't want to make a new args struct each time for adding). However, the "named parameter idiom" (also called fluent interface pattern") can be useful for parameter building to e.g., enforce required/optional parameters. – AndyG May 12 '21 at 19:56
  • 1
    In C++20, the call can be a one-liner too thanks to the designated initializer syntax. [Example](https://godbolt.org/z/qosfs1hcG). – mediocrevegetable1 May 12 '21 at 19:57
  • @mediocrevegetable1: Indeed, designated initializers probably deserve their own mention in the answer. – AndyG May 12 '21 at 19:59