使用另一个构造函数的默认结构构造

Default struct construct with another constructor

以下代码无法编译,因为实例参数与构造函数参数不匹配。如果我删除它编译并运行的构造函数。我希望能够以任何一种方式使用它——用字符串构造或直接成员变量初始化。 (这是我真正想要做的事情的最小版本。)我需要另一个带有初始化列表或类似列表的构造函数吗?

具体来说,我不想添加另一个带有两个 int 的构造函数,我想使用删除字符串构造函数时使用的机制。

#include <iostream>
#include <string>
struct S
{
    int m_a;
    int m_b;
    
    S(const std::string s):
        m_a(99),
        m_b(99)
    {std::cout << "ctor runs" << std::endl;}
    
    friend std::ostream& operator<<(std::ostream& os, const S& s)
    {  os << "S: " << s.m_a << ", "  << s.m_b; }
};

int main()
{
    S s{1,2};
    std::cout << s << std::endl;
}

你想要的是不可能的。您的选择是:

  1. 不要定义构造函数并使用聚合初始化。
  2. 为您想要的每组参数定义构造函数并实现它们以完全按照您想要的方式运行。

选项互斥。

Do I need another constructor with an initialiser list or similar?

您可以定义接受 std::initializer_list 的构造函数。这比定义一个接受两个整数的构造函数更糟糕。

I want to use the mechanism that is used if I delete the string constructor.

您将能够通过删除字符串构造函数来使用该“机制”。


P.S。您通常应该避免按值传递字符串。

一旦您添加了用户提供的构造函数,您的 class 就不再是聚合。这意味着你不能直接用

构造对象
S s{1,2};

除非你定义了合适的构造函数。在这种情况下,它就像添加

一样简单
S(int a, int b) : m_a(a), m_b(b) {}

现在可以通过两个 int 或任何可以隐式转换为 int.

的方式来创建 S

Specifically, I don't want to add another constructor with two ints, I want to use the mechanism that is used if I delete the string constructor.

简而言之,这就是采用两个 int 的构造函数所做的。它允许您创建对象,就好像它是一个聚合,即使它不是。也就是说,要获得完全相同的功能,您需要提供默认值,例如

S(int a = 0, int b = 0) : m_a(a), m_b(b) {}

现在

S a{};
S b{1};
S c{1, 2};

全部编译但

S d{1, 2, 3};

不会。