3

私はC++0xのよくある質問を読んでいて、初期化子リストの詳細を説明しているセクションに出くわしました。例は主に次のバリエーションでした。

vector<int> vi = { 1, 2, 3 };
vector<int> vj({1, 2, 3});
// etc.

ただし、次のフォームもリストされています。

vector<int> vk{2};

この形式はよくある質問の他の場所にありますが、最初の2つの形式と意味的に異なるのか、それとも単に構文上の糖衣構文とは異なるのかについて興味がありvk({x, y, z})ます。

4

3 に答える 3

6

({1, 2, 3})フォームはのコンストラクターを直接呼び出し、最初vector<int>の引数としてaを渡します{1, 2, 3}。あなたはもっと多くの議論を渡すことができたでしょう

vector<int> vk({1, 2, 3}, myAllocator);

vector<int>最初のパラメーターがまたは(別のコンテナークラスなど)initializer_listによって初期化できる別のタイプのコンストラクターがない場合は、機能しません。{1, 2, 3}あなたの場合vector<int>、実際には最初のパラメーターが。であるコンストラクターがあるため、これは機能しますinitializer_list<int>。これは通常の関数呼び出しと同じです

void f(vector<int> const& vk);
int main() { f({1, 2, 3}); }

のように括弧を省略した場合vector<int> vk{1, 2, 3}、正確な意味はクラスによって異なります。Avector<int>には、初期化子リストコンストラクターがあります。これは、タイプの最初のパラメーターinitializer_list<int>(オプションでそれへの参照)を持つコンストラクターであり、他のすべてのパラメーターにはデフォルトの引数があります。クラスにそのようなコンストラクターがある場合、初期化子リストがそのコンストラクターに渡されます。あるいは、クラスは単純に集合体(たとえば、初期化子リストがメンバーを初期化する)にすることも、個別の引数struct A { int a; int b; int c; };を受け入れるコンストラクターを持つこともできます。3int

最後に、= { 1, 2, 3 }形式は括弧を省略したバージョンとほぼ同じです(つまり、削除するだけです=)。ただし、明示的なコンストラクターを使用することは禁止されています(つまり、明示的なコンストラクターとして宣言した場合、explicit vector(initializer_list<int>);またはexplicit vector(int, int, int);代わりに宣言した場合は、を使用するとエラーが発生します= { 1, 2, 3 }) 。 。

于 2011-08-12T20:23:29.580 に答える
1

1つは均一な初期化であり、もう1つは初期化リストです。これらは2つの異なるものですが、ご覧のとおり、同様の構文を生成できます。

vector<int> vk{2};

は統一された初期化です-他の2つは初期化リストです。

于 2011-08-12T18:02:20.753 に答える
0

均一な初期化により、変換、つまりデータの損失を引き起こす変換の絞り込みが防止されます。

#include <vector>

std::vector<float> v{1.0F, 2.0F, 3.0F}; // OK: 

std::vector<float> w{1.0, 2.0, 3.0}; // OK: doubles could be put into floats without loss.

std::vector<int> j{1.1, 2.2, 3.3}; // error: narrowing

std::vector<int> k{1L, 2L, 3L}; // OK: the long numbers can be represented as int without loss.

std::vector<int> l{0xfacebeefL, 0xdeadbabeL, 0xfadecabeL}; // error: narrowing.
于 2011-08-13T01:06:47.243 に答える