Chris
Chris

Reputation: 31286

C++ default arguments out of order?

suppose I have:

void f(bool option1 = false, bool option2 =false, bool option3 = false) 
{
     ... 
}

And I want to call:

f(option2=true);

Is this possible in C++?

Upvotes: 6

Views: 3286

Answers (4)

Sergey Kalinichenko
Sergey Kalinichenko

Reputation: 727067

I have 12 optional parameters

If all your optional parameters are of type bool, you could use a flag enum:

enum class OptionFlags {
    Option1 = 1,
    Option2 = 2,
    Option3 = 4,
    Option4 = 8
};

inline OptionFlags operator|(OptionFlags a, OptionFlags b) {
    return static_cast<OptionFlags>(static_cast<int>(a) | static_cast<int>(b));
}

Now you can define your function as follows:

void f(OptionFlags f) {
    ...
}

which users would call like this:

f(OptionFlags::Option1 | OptionFlags::Option3); // Option1==true, Option3==true

Upvotes: 3

Vittorio Romeo
Vittorio Romeo

Reputation: 93384

It is not possible to invoke a function in the manner you suggested in C++. You can emulate named parameters via metaprogramming or simply pass a struct to your function. E.g.

struct options
{
    bool option0{false};
    bool option1{false};
    bool option2{false};
}; 

void f(options opts = {});

C++11 usage:

options opts;
opts.option2 = true;
f(opts);

C++2a usage:

f({.option2=true});

Upvotes: 14

463035818_is_not_an_ai
463035818_is_not_an_ai

Reputation: 123440

No you cannot do that, the names of the parameters are so to speak nonexistant at the call site. There are several ways to work around that. Actually I would already say that 3 bool parameters alone is already a reason do actively do something to avoid confusion for the caller and allow the user to have proper names.

Some might not like this simplistic approach, but it may serve as a starting point:

struct f_params {
    bool a;
    bool b;
    bool c;
    f_params() : a(false),b(false),c(false) {}
    f_params& set_a(bool x) { 
        a = x;
        return *this;
    }
};

The caller may now set only the non-defaults:

f_params x;
x.a = true;
f(x);
// or..
f(f_params().set_a(true));

Upvotes: 1

Jarod42
Jarod42

Reputation: 218323

As alternative, you might use bit flag:

enum FOption
{
    option0 = 1 << 0,
    option1 = 1 << 1,
    option2 = 1 << 2,
};

void f(FOption opt = 0) {
    const bool opt0 = opt & option0;
    const bool opt1 = opt & option1;
    const bool opt2 = opt & option2;
    /*...*/
}

and then use it like:

f(option2);
f(option1 | option2);

Upvotes: 4

Related Questions