私は次のコンストラクタを持つクラス表現型を持っています:
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
ただし、このような初期化はデフォルトで配列を構築し、代入演算子を使用します。速度と安全性を目指している場合(イニシャライザーが多すぎるとコンパイル時エラーが発生します!)、可変長テンプレートを使用して通常のコンストラクターを使用することもできます。
ただし、これは必要以上に汎用的な場合があります(多くの場合、特に単純な整数の場合は、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
にコピーします。しかし、それは呼び出しを本当にしたいものではありません:)
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 ...
};
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};
}