2010-11-07 76 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}; 
}