C++20:强制使用指定的初始值设定项来模拟命名函数参数

C++20: Force usage of designated initializers to emulate named function arguments

我非常喜欢使用临时结构和指定的初始值设定项来为我的函数模拟命名参数。

struct Args {
    int a;
    int b;
};

int f(Args a) {
    return a.a + a.b;
}

int g() {
    return f({.a = 1, .b = 2}); // Works! That's what I want.
    return f({1, 2}); // Also works. I want to forbid this, though.
}

但是,这些结构仍然可以通过位置初始化列表进行初始化。也就是说,您仍然可以调用 f({1, 2}).

我想禁止这样做并强制调用者也在调用站点显式命名参数。 我如何在 C++20 中这样做?

最好的方法就是代码审查。告诉人们使用指定的初始值设定项。指定初始化器很棒,人们喜欢使用它们。这与其说是技术问题,不如说是社会问题。

如果你真的想推动一下,你总是可以先坚持一些真正糟糕的数据成员,就像这样:

class Args {
    struct Key { explicit Key() = default; };
    struct StopIt { StopIt(Key) { } };

public:
    StopIt asdfjkhasdkljfhasdf = Key();

    int a;
    int b;
};

Args 仍然是一个集合,我们只是有这个额外的前导数据成员拼写了我敲键盘时出现的任何内容。它有一个默认的成员初始值设定项 - 但是该初始值设定项是 Args 私有的,只有 Args 知道如何构造它。

所以用户不能正确地为特定成员提供初始化器,他们必须依赖默认成员初始化器来初始化它正确。由于它先行,它们必须依赖指定的初始化才能初始化任何其他成员。

而且……写这样的东西是不是有点傻?直接告诉人家用指定初始化就好了


从技术上讲,他们可以在这种情况下写 f({Args().asdfjkhasdkljfhasdf, 1, 2}),但这似乎是我们在这一点上的荒谬或恶意。