括号括起的初始化程序列表构造函数 [英] Brace-enclosed initializer list constructor

查看:82
本文介绍了括号括起的初始化程序列表构造函数的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我的类Phenotype具有以下构造函数:

I have class Phenotype with the following constructor:

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};

输出:

$ 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?

推荐答案

它只能用于聚合(数组和某些类。与流行的看法相反,这也适用于许多非荚) 。编写带它们的构造函数是不可能的。

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.

由于您将其标记为 C ++ 0x,因此这是可能的。神奇的词是 initializer-list构造函数。就像

Since you tagged it as "C++0x", then this is possible though. The magic words is "initializer-list constructor". This goes like

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.

这可能比需要的泛型(通常,initializer_list完全可以满足要求,特别是对于纯整数而言)。它得益于完美的转发功能,因此可以将右值参数构造为数组元素

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

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 ,因此它可以使用副本表型的构造函数,构造一个临时的表型对象,并将其复制到 p3 。但这不是我们真正想要的电话:)

Edit Correction, 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 :)

这篇关于括号括起的初始化程序列表构造函数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆