2012-06-23 1 views
29

ベクトルの値を取得したい場合は、[]演算子を使用して2つのオプションを使用できます。それとも私が使用するための例.AT機能を使用する場合があります。なぜ "vector.at(x)"を "vector [x]"よりもC++で使うのが良いですか?

vector<int> ivec; 
ivec.push_back(1); 

を今、私は私が使用して聞いた両方のもの

int x1 = ivec[0]; 
int x2 = ivec.at(0); // or 

を行うことができます私は、そのオプションを使用する場合、私はこれを投げることができるので、より良いオプションです1つは例外です。

誰か説明していただけますか?

+3

「違いは何ですか?」良い質問です。答えは、1)自動レンジチェック(.at()は範囲外の例外をスローし、[]は暗黙に失敗する)、2)個人的な好み - どちらの構文がより好きですか? "どちらが良いですか"、一方では価値判断です。答えは必然的に "それは依存する"。 IMHO ... – paulsm4

+11

誰も優れているわけではありません。 –

答えて

54

c[i]c.at(i)の違いはiベクトルの範囲外である場合operator[]は単に何かが起こることを意味しており、未定義の動作を起動しながら​​は、std::out_of_range例外をスローすることです。

at()operator[]より優れています。それは状況によって異なります。 at()は範囲チェックを実行するので、特にコード自体がインデックスが範囲外になることがないようにする場合は、常に望ましいとは限りません。そのような場合は、operator[]が良いです。 operator[]は常にat()メンバ関数と比較してより良い選択である、このようなループでは

for(size_t i = 0 ; i < v.size(); ++i) 
{ 
    //Should I use v[i] or v.at(i)? 
} 

は、次のループを考えてみましょう。

インデックスが無効な場合に例外をスローしたい場合はを好むので、catch{ ...}ブロックで代替作業を行うことができます。

ここ
try 
{ 
    size_t i = get_index(); //I'm not sure if it returns a valid index! 

    T item = v.at(i); //let it throw exception if i falls outside range 

    //normal flow of code 
    //... 
} 
catch(std::out_of_range const & e) 
{ 
    //alternative code 
} 

あなたはそれが有効な指標であることを確認するために、iを自分で確認し、at()の代わりにoperator[]を呼び出すことができますが、:例外は、あなたがとして例外的/代替コードから通常のコードを分離役立ちますif-elseブロックを使用して通常のコードと代替コードを混ぜると、コードの正常な流れを読むことが難しくなります。上記の場合、try-catchは、が代替コードから正常なコードを実際に分けてしまうため、コードの可読性が向上し、きれいで清潔なコードになります。

+4

"誰も' at() 'がいいとは言いません。あなたは驚くだろう。 –

+0

@KonradRudolph:何ですか? – Nawaz

+7

そこに何人の馬鹿がいるのか、それらのどれくらいがC++を教えるのかを過小評価しないでください。 ;-) –

10

at[]の唯一の違いは、atが範囲チェックを実行し、[]が唯一の違いであることです。範囲を既にチェックしているか、または範囲外になることができないようにインデックスを構築してアイテムに繰り返しアクセスする必要がある場合は、atの代わりに[]を選択することで数回のCPUサイクルを節約できます。1つのチェック及び複数のアクセス

例:

size_t index = get_index(vect); 
if (index < 0 || index >= vect.size()) return; 
if (vect[index] > 0) { 
    // .... 
} else if (vect[index] > 5) { 
    // .... 
} else .... 

インデックスは内部制限可能に構成されている場合の例:

for (size_t i = 0 ; i != vect.size() ; i++) { 
    if (vect[i] > 42) { 
     // .... 
    } 
} 
0

他の答えが全く正しいかもしれないが、デバッグ中のコードを記述する際には、エラーが発生するため、at()を使用することをお勧めします。これは一般的なケースですが、広く普及しているコンパイラには適用されません - gccはputting it in debug modeで致命的な範囲チェックを実行するように設定されている可能性があります。

0

ベクトルメソッドC++ .atは、要素がベクトルに存在せず、例外がスローされた場合に境界をチェックします。

[]を使用している場合、ベクタに対して境界チェックが実行されないため、その要素が存在しない場合、例外はスローされず、結果はベクトル内に存在しないelemntsのランダム値を持つような未定義の動作になります。

[]を使用すると、安全性の面ではatより優れていますが、これは時間がかかり、プログラムのパフォーマンスに影響します。

関連する問題