大括号封闭的初始化列表构造函数
Posted
技术标签:
【中文标题】大括号封闭的初始化列表构造函数【英文标题】:Brace-enclosed initializer list constructor 【发布时间】:2011-05-06 07:18:55 【问题描述】:我有具有以下构造函数的类表型:
Phenotype(uint8 init[NUM_ITEMS]);
我可以像这样创建一个表型:
uint8 data[] = 0,0,0,0,0;
Phenotype p(data);
但是当我尝试这样创建一个时出现错误:
Phenotype p = 0,0,0,0,0;
输出:
$ 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*)
该错误似乎表明有一种方法可以定义一个构造函数,该构造函数采用大括号括起来的初始值设定项列表。有谁知道如何做到这一点?
【问题讨论】:
can we pass arrays as arguments to functions by this syntax, under upcoming c++0x standards ?的可能重复 【参考方案1】:它只能用于聚合(数组和某些类。与流行的看法相反,这也适用于许多非 Pod)。编写一个接受它们的构造函数是不可能的。
由于您将其标记为“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 p11, 2, 3;
Phenotype p2(1, 3, 2); // works too
Phenotype p3(1, 2, 3); // doesn't work
但是,这样的初始化会默认构造数组,然后使用赋值运算符。如果您的目标是速度和安全(您会因为太多初始化程序而出现编译时错误!),您还可以使用带有可变参数模板的普通构造函数。
这可能比需要的更通用(通常一个 initializer_list 就足够了,尤其是对于纯整数)。它得益于完美转发,因此可以将右值参数构造为数组元素
template<typename ...T>
Phenotype(T&&...t):m_array std::forward<T>(t)...
// used like
Phenotype p11, 2, 3;
Phenotype p2(1, 2, 3); // works too
Phenotype p3(1, 2, 3); // doesn't work
这是一个艰难的选择!
编辑更正,最后一个也可以,因为我们没有创建explicit
的构造函数,所以可以使用Phenotype
的复制构造函数,构造一个临时的Phenotype
对象并将其复制到p3
。但这不是我们真正想要的调用:)
【讨论】:
非常有帮助。一直在寻找这个问题的答案 他将其标记为 c++11。但是为什么它在 c++11 中不起作用? @Johanes 这种初始化是否需要额外的解构函数? 有没有办法指定T
不能是Phenotype
?这取代了我的默认移动构造函数...【参考方案2】:
在 C++0x 中,您似乎可以为此创建一个构造函数。我自己没有这方面的经验,但它看起来好像叫做initializer list-constructor。
容器可能会像这样实现初始化列表构造函数:
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 ...
;
【讨论】:
【参考方案3】:您需要使用 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;
【讨论】:
以上是关于大括号封闭的初始化列表构造函数的主要内容,如果未能解决你的问题,请参考以下文章
为啥在使用大括号初始值设定项列表时首选 std::initializer_list 构造函数?