题
我具有以下构造函数的类表型:
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*)
该错误似乎表明有一种方法可以定义构造函数,该构造函数获取了括号封闭的初始化器列表。有人知道这可能是如何做到的吗?
解决方案
它只能针对聚集体(数组和某些类别。与普遍的信念相反,这也适用于许多非底子)。编写一个接管它们的构造函数是不可能的。
由于您将其标记为“ 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
但是,此类初始化将默认构造数组,然后使用分配运算符。如果您的目标是速度和安全性(对于太多的初始化器而言会收到编译时间错误!),您也可以使用带有variadic模板的普通构造函数。
不过,这可能比所需的更通用(通常是initializer_list完全足够,尤其是对于普通整数而言)。它受益于完美的转发,因此可以将rvalue论点移动到数组元素中
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
这是一个艰难的选择!
编辑 更正,最后一个也可以工作,因为我们没有制作构造函数 explicit
, ,因此可以使用 Phenotype
, ,建造一个临时 Phenotype
对象并将其复制到 p3
. 。但这不是我们真正想要的电话:)
其他提示
在C ++ 0x中,您似乎可以为此创建一个构造函数。我本人没有它的经验,但看起来很称为 初始化列表构造仪.
容器可能会实现这样的初始列表构造函数:
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 ...
};
您需要使用std :: prinitizer_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};
}
不隶属于 StackOverflow