C ++默认参数乱序?


C++ default arguments out of order?

假设我有:

1
2
3
4
void f(bool option1 = false, bool option2 =false, bool option3 = false)
{
     ...
}

我想打电话给:

1
f(option2=true);

在C++中这是可能的吗?


以C++中建议的方式调用函数是不可能的。您可以通过元编程来模拟命名参数,也可以简单地将struct传递给您的函数。例如。

1
2
3
4
5
6
7
8
struct options
{
    bool option0{false};
    bool option1{false};
    bool option2{false};
};

void f(options opts = {});

C++ 11用法:

1
2
3
options opts;
opts.option2 = true;
f(opts);

C++ 2A用法:

1
f({.option2=true});


作为替代方案,您可以使用位标志:

1
2
3
4
5
6
7
8
9
10
11
12
13
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;
    /*...*/
}

然后像这样使用:

1
2
f(option2);
f(option1 | option2);


I have 12 optional parameters

如果所有可选参数都是bool类型,则可以使用标志枚举:

1
2
3
4
5
6
7
8
9
10
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));
}

现在,您可以定义函数如下:

1
2
3
void f(OptionFlags f) {
    ...
}

哪些用户会这样称呼:

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

不,您不能这样做,参数的名称就是说在调用站点不存在。有几种方法可以解决这个问题。实际上,我已经说过,单独使用3个bool参数已经是主动做一些事情以避免对调用者造成混淆并允许用户使用正确的名称的原因。

有些人可能不喜欢这种简单的方法,但它可能是一个起点:

1
2
3
4
5
6
7
8
9
10
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;
    }
};

调用者现在只能设置非默认值:

1
2
3
4
5
f_params x;
x.a = true;
f(x);
// or..
f(f_params().set_a(true));