2017-10-16 3 views
-1

私はC++を初めて使用しています。私はこのコードを持っています:VECTOR初期化C++

int main() 
{ 
    vector<int> a = { 1,2,3,4,5,6 }; 

    vector<int> b(&a[0], &a[5]); // what's wrong? Is it completely wrong this way? 

    for (int i = 0; i < 6; i++) { 
     cout << b[i] << endl; 
    } 
    return 0; 
} 

私は正しい方法を知っています。 b [5]はどこにあり、なぜこのコードでアクセスできないのか教えてください。

+0

を書く '&することができます[0]' - > 'a.begin()'& '&[5]' - > 'a.end()あなたは割り当てませんでした' – George

+0

それ。 –

+1

'私は6 <;'なぜあなたはマジックナンバーを使用していますか?ベクトルはサイズを知っていて、bのサイズは6ではありません! –

答えて

3
vector<int> b(&a[0], &a[5]); 

建設のこの種のstd::vectorのIteratorベースのコンストラクタを使用しています。 Iteratorコンストラクタは、開始部分と終了部分の2つのイテレータを受け取ります。あなたは始まりと終わりを過ぎています。つまり、新しいベクトルはオリジナルのサイズよりも1桁小さい範囲に構築されます。

は、あなたがこの構文にコミットしている場合、正しい方法は、あなただけのベクトルをコピーする場合、それは

vector<int> b(a.begin(), a.end()); 

になり書くために、しかし、これは不要です。あなたは、ベクターの一部をコピーしたい場合は、

vector<int> b = a; //b is now a copy of a, using its own memory 

実際のイテレータを使用します:あなたは代入演算子とそれをコピーする必要がありますC++で

vector<int> b(a.begin() + 2, a.begin() + 5);//Copies a[2], a[3], a[4] into a vector of size 3. 
3

最後のイテレータは、より前のの範囲内の最後の項目です。 &a[6]と言うこともできますが、vector<int> b(a.begin(), a.end());のようなコンテナの組み込みイテレータを使用する方がよいでしょう。

さらに、vector<int> b {a};はコピーコンストラクタを使用しているため、イテレータやポインタを使用することは特にありません。 (これは推奨されていないもののイテレータがその実施し、可能な行動の癖をカプセル化し、一般的に安全であることから、単にポインタを使用することのできる)

1

範囲は、フォーム

で指定されています
[first, last) 

角かっこの代わりに閉じ括弧は、許容値に値lastが含まれていないことを示します。この宣言

vector<int> b(&a[0], &a[5]); 

ポインタ(イテレータ)の許容範囲内のこのよう

値が&a[5]ベクトルbの初期化に使用されないポインタが指す[&a[0], &a[5])あります。ベクトルはa[0], a[1], a[2], a[3] and a[4]に等しい5つの要素しか持たない。

だから、このループではマジックナンバー6未定義の動作で

for (int i = 0; i < 6; i++) { 
    cout << b[i] << endl; 
} 

結果を使用して。

あなたが例えば

for (size_t i = 0; i < b.size(); i++) 
{ 
    std::cout << b[i] << std::endl; 
}  

か、単に

for (auto x : v) std::cout << x << std::endl; 

を書くことができ、

vector<int> b(a); 

のようなベクトルbを初期化する方が簡単だろうと明らかである。しかし、あなたがしたい場合ベクトルの初期化などのベクターaのいくつかの範囲を指定しますそして、あなたが例えば

#include <iterator> 

//... 

vector<int> b(a.begin(), std::next(a.begin(), 6));