C++ 大括号封闭的初始化列表构造函数
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/4118025/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Brace-enclosed initializer list constructor
提问by bretttolbert
I have class Phenotype with the following constructor:
我有具有以下构造函数的类 Phenotype:
Phenotype(uint8 init[NUM_ITEMS]);
I can create a Phenotype like this:
我可以创建这样的表型:
uint8 data[] = {0,0,0,0,0};
Phenotype p(data);
But I get an error when I try to create one like this:
但是当我尝试创建这样的一个时出现错误:
Phenotype p = {0,0,0,0,0};
Output:
输出:
$ make
g++ -Wall -g main.cpp -std=c++0x
main.cpp: In function ‘int main(int, char**)':
main.cpp:109: error: no matching function for call to ‘Phenotype::Phenotype(<brace-enclosed initializer list>)'
main.cpp:37: note: candidates are: Phenotype::Phenotype(uint8*)
The error seems to indicate that there is a way to define a constructor which takes a brace-enclosed initializer list. Does anyone know how this might be done?
该错误似乎表明有一种方法可以定义一个构造函数,该构造函数采用大括号括起来的初始值设定项列表。有谁知道如何做到这一点?
回答by Johannes Schaub - litb
It can only be done for aggregates (arrays and certain classes. Contrary to popular belief, this works for many nonpods too). Writing a constructor that takes them is not possible.
它只能用于聚合(数组和某些类。与流行的看法相反,这也适用于许多非 pod)。编写一个接受它们的构造函数是不可能的。
Since you tagged it as "C++0x", then this is possible though. The magic words is "initializer-list constructor". This goes like
由于您将其标记为“C++0x”,因此这是可能的。神奇的词是“初始化列表构造函数”。这就像
Phenotype(std::initializer_list<uint8> c) {
assert(c.size() <= std::size(m_array));
std::copy(c.begin(), c.end(), m_array);
}
// used like
Phenotype p1{1, 2, 3};
Phenotype p2({1, 3, 2}); // works too
Phenotype p3(1, 2, 3); // doesn't work
However, such initialization will default construct the array and then use the assignment operator. If you aim for speed and safety (you get compile time errors for too many initializers!), you can also use an ordinary constructor with a variadic template.
但是,这种初始化将默认构造数组,然后使用赋值运算符。如果您的目标是速度和安全(太多初始化程序会导致编译时错误!),您还可以使用带有可变参数模板的普通构造函数。
This can be more generic than needed though (often an initializer_list completely suffices, especially for plain integers). It benefits from perfect forwarding, so that an rvalue argument can be move constructed into an array element
尽管这可能比需要的更通用(通常一个 initializer_list 就完全足够了,尤其是对于普通整数)。它受益于完美的转发,因此可以将右值参数移动到数组元素中
template<typename ...T>
Phenotype(T&&...t):m_array{ std::forward<T>(t)... } {
}
// used like
Phenotype p1{1, 2, 3};
Phenotype p2(1, 2, 3); // works too
Phenotype p3({1, 2, 3}); // doesn't work
It's a hard choice!
这是一个艰难的选择!
EditCorrection, the last one works too, as we didn't make the constructor explicit
, so it can use the copy constructor of Phenotype
, constructing a temporary Phenotype
object and copy it over to p3
. But that's not what we really would want the calls to be :)
编辑更正,最后一个也有效,因为我们没有创建构造函数explicit
,所以它可以使用 的复制构造函数Phenotype
,构造一个临时Phenotype
对象并将其复制到p3
。但这不是我们真正想要的电话:)
回答by Magnus Hoff
In C++0x it seems you can create a constructor for this. I have no experience with it myself, but it looks like it's called initializer list-constructor.
在 C++0x 中,您似乎可以为此创建一个构造函数。我自己没有使用它的经验,但它看起来像是称为initializer list-constructor。
A container might implement an initializer-list constructor like this:
一个容器可能会实现一个初始化列表构造函数,如下所示:
template<class E> class vector {
public:
vector (std::initializer_list<E> s) // initializer-list constructor
{
reserve(s.size()); // get the right amount of space
uninitialized_copy(s.begin(), s.end(), elem); // initialize elements (in elem[0:s.size()))
sz = s.size(); // set vector size
}
// ... as before ...
};
回答by evnu
You need to use the std::initializer_list template type. Example:
您需要使用 std::initializer_list 模板类型。例子:
#include <iostream>
class X {
public:
X (std::initializer_list<int> list) {
for (auto i = list.begin(); i != list.end(); i++) {
std::cout << *i << std::endl;
}
}
};
int main () {
X x = {1,2,3,4,5};
}