2010-11-07 47 views
38

我有类表型与下面的构造:括号内的初始化列表构造

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*) 

该错误似乎表明有一种方法来定义一个构造函数,该构造函数接受一个大括号包含的初始化程序列表。有谁知道这可能会怎么做?

+0

可能重复(http://stackoverflow.com/questions/3424727/can-we-传递数组作为参数的功能,通过这种语法下即将到来的c0x) – kennytm 2010-11-07 14:04:50

回答

66

它只能用于聚集(数组和特定的类,与流行的观点相反,它也适用于很多非物理)。编写一个构造函数是不可能的。

既然你把它标记为“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 

但是,这样的初始化将默认构造数组,然后使用赋值运算符。如果你的目标是速度和安全性(编译时错误太多的初始化器!),你也可以使用带有可变参数模板的普通构造器。

这可能比需要更通用(通常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 

这是一个艰难的选择!

编辑修正,最后一个工作过,因为我们没有做的构造explicit,所以它可以使用拷贝构造函数Phenotype,构建一个临时Phenotype对象,将其复制到p3。但这不是我们真正希望的调用:)

+0

非常有帮助。一直在寻找答案这一段时间 – 2013-10-30 21:48:14

+2

他把它标记为C++ 11。但是,它如何在C++ 11中不起作用呢? – 2015-05-10 15:50:39

6

在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模板类型。例如:[?可以通过我们此语法传递数组作为函数的参数,即将下的C++ 0x标准]

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