c[i]
との違いは、ベクトルの範囲外にある場合に例外c.at(i)
をat()
スローする一方で、単に未定義の動作を呼び出すことです。つまり、何でも起こり得るということです。std::out_of_range
i
operator[]
at()
より優れているとは誰も言いませんoperator[]
。それは状況に依存します。asat()
は範囲チェックを実行しますが、常に望ましいとは限りません。特に、コード自体がインデックスが決して範囲外にならないことを確認している場合はなおさらです。そのような場合は、operator[]
より良いです。
次のループを検討してください。
for(size_t i = 0 ; i < v.size(); ++i)
{
//Should I use v[i] or v.at(i)?
}
このようなループでは、メンバー関数operator[]
と比較して常により良い選択です。at()
無効なインデックスの場合に例外をスローして、ブロック内で別の作業を実行できるようにしたいat()
場合に使用し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
呼び出すことができますが、通常のコードと block を使用する代替コードが混在し、コードの通常の流れを読み取ることが難しくなります。上記のように、コードの可読性が向上します。これにより、通常のコードが代替コードから実際に分離され、すっきりとしたクリーンなコードが得られます。operator[]
at()
if-else
try-catch