如何编写适当的std :: initializer_list构造函数

How to write proper std::initializer_list constructor

本文关键字:initializer list 构造函数 std 何编写      更新时间:2023-10-16

请考虑以下代码:

#include <iostream>
#include <vector>
struct C {
    std::vector<int> a;
    std::string b;
    bool c;
};
void printC(const C &c) {
    // ...
}
int main() {
    printC({
        { 1, 2, 3 },
        "ehlo",
        false
    });
}

这有效,因为编译器可以为我生成适当的构造函数。但是,如果我将结构C更改为此:

struct C {
    std::vector<int> a;
    std::string b;
    bool c;
    C() {
        c = false;
    }
};

printc调用停止工作,因为编译器停止生成适当的构造函数。我试图使用std :: prinitizer_list写一个构造函数,但失败了。

所以问题是 - 如何编写将使上述代码编译并再次工作的构造函数?

我试图使用std :: pinitializer_list为自己写一个构造函数,但失败了。

您不需要一个。您只需要一个c'tor带一个矢量,字符串和布尔值:

C(std::vector<int> a, std::string b, bool c) 
  : a(std::move(a))
  , b(std::move(b))
  , c(c) {
}

您的代码现在应该再次构成良好。尽管现在它会产生两个移动操作,而原始的汇总版本可以直接初始化对象的元素。这是值得考虑的事情。

值得注意的是,在C 14中,您可以只使用默认成员初始器:

struct C {
    std::vector<int> a;
    std::string b;
    bool c = false;
};

另外,汇总初始化不会生成构造函数。它完全绕过它们。

您可以通过std::initializer_list<int>的实例这样:

#include <initializer_list>
struct C {
    /* Data members... */
    C(std::initializer_list<int> vecData, std::string str, bool flag) :
        a{vecData}, b{std::move(str)}, c{flag} {}
};