如何编写正确的 std::initializer_list 构造函数
How to write proper std::initializer_list constructor
考虑以下代码:
#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 为自己编写一个构造函数,但失败了。
所以问题是 - 如何编写使上述代码再次编译和工作的构造函数?
I've tried to write myself a constructor using std::initializer_list but failed.
你不需要一个。您只需要一个接受向量、字符串和布尔值的 c'tor:
C(std::vector<int> a, std::string b, bool c)
: a(std::move(a))
, b(std::move(b))
, c(c) {
}
您的代码现在应该再次合式了。虽然现在它会产生两个移动操作,而原始聚合版本可以直接初始化对象的元素。这是值得考虑的事情。
您可以像这样传递 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} {}
};
值得注意的是,在 C++14 及更高版本中,您可以只使用默认成员初始化程序:
struct C {
std::vector<int> a;
std::string b;
bool c = false;
};
此外,聚合初始化不生成构造函数。它完全绕过了它们。
考虑以下代码:
#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 为自己编写一个构造函数,但失败了。
所以问题是 - 如何编写使上述代码再次编译和工作的构造函数?
I've tried to write myself a constructor using std::initializer_list but failed.
你不需要一个。您只需要一个接受向量、字符串和布尔值的 c'tor:
C(std::vector<int> a, std::string b, bool c)
: a(std::move(a))
, b(std::move(b))
, c(c) {
}
您的代码现在应该再次合式了。虽然现在它会产生两个移动操作,而原始聚合版本可以直接初始化对象的元素。这是值得考虑的事情。
您可以像这样传递 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} {}
};
值得注意的是,在 C++14 及更高版本中,您可以只使用默认成员初始化程序:
struct C {
std::vector<int> a;
std::string b;
bool c = false;
};
此外,聚合初始化不生成构造函数。它完全绕过了它们。