如何编写正确的std :: initializer_list构造函数

时间:2018-12-20 07:59:59

标签: c++ c++11 constructor initializer-list

考虑以下代码:

#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 :: initializer_list编写自己的构造函数,但失败了。

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

3 个答案:

答案 0 :(得分:7)

  

我尝试使用std :: initializer_list编写自己的构造函数,但失败了。

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

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

您的代码现在应该再次格式正确。尽管现在它需要进行两次移动操作,而原始的聚合版本本可以直接初始化对象的元素。这值得考虑。

答案 1 :(得分:5)

值得注意的是,在C ++ 14和更高版本中,您可以使用默认的成员初始化程序:

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

此外,聚合初始化不会生成任何构造函数。它会完全绕开它们。

答案 2 :(得分:1)

您可以像这样传递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} {}
};