Вопрос по exception, c++, vector – Почему использование «vector.at (x)» лучше, чем «vector [x]» в C ++?

29

Если я хочу получить значение в векторе, я могу использовать две опции: использовать оператор []. Или я мог бы использовать функцию .at пример для использования:

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

Теперь я могу сделать обе вещи

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

Я слышал, использование at - лучший вариант, потому что когда я использую этот параметр, я могу выбросить его в исключение.

Может кто-нибудь, пожалуйста, объясните это?

Никто не лучше, они служатsimilar but different цели. K-ballo
"В чем разница?" хороший вопрос Ответ таков: 1) автоматическая проверка диапазона (.at () сгенерирует исключение за пределами диапазона, [] молча потерпит неудачу), и 2) личные предпочтения - какой синтаксис вам больше нравится. «Что лучше?», с другой стороны, является оценочным суждением. Ответ обязательно «Это зависит». ПО МОЕМУ МНЕНИЮ... paulsm4

Ваш Ответ

4   ответа
10

Единственная разница междуat а также[] в том, чтоat выполняет проверку диапазона и[] не. Если вы уже проверили диапазон или построили свой индекс таким образом, что он не может выйти за пределы диапазона, и вам необходимо многократно обращаться к элементу, вы можете сэкономить несколько циклов ЦП, выбрав[] вместоat.

Пример одиночной проверки и множественного доступа:

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) {
        // ....
    }
}
54

Разница междуc[i] а такжеc.at(i) в том, чтоat() бросаетstd::out_of_range исключение, еслиi выходит за пределы диапазона вектора, в то время какoperator[] просто вызывает неопределенное поведение, что означает, что все может произойти.

Никто не говоритat() лучше, чемoperator[], Это зависит только от обстоятельств. Какat() выполняет проверку диапазона, это может быть нежелательно всегда, особенно если ваш код сам по себе гарантирует, что индекс никогда не выйдет за пределы диапазона. В таких случаях,operator[] лучше.

Рассмотрим следующий цикл:

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

В такой петлеoperator[] всегда лучший выбор по сравнению сat() функция-член.

я бы предпочелat() когда я хочу, чтобы это выдало исключение в случае неверного индекса, чтобы я мог сделать альтернативную работу вcatch{ ...} блок.Exceptions help you separate the normal code from the exceptional/alternative code as:

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 самостоятельно, чтобы убедиться, что это допустимый индекс, а затем вызватьoperator[] вместоat(), но это будет смешивать нормальный код с альтернативным кодом, используяif-else блок, который затрудняет чтениеthe normal flow of code, Если вы видите выше,try-catch улучшает читабельность кода, так какreally separates нормальный код из альтернативного кода, в результате получается аккуратный и чистый код.

@KonradRudolph: что?
Не стоит недооценивать, сколько там идиотов, и сколько из них обучают C ++. ;-)
& # x201C; Никто не говоритat() лучше & # x201D; & # X2013; ха! Вы будете удивлены.
Я хотел бы указать вам на эту простую цитату:There are 2 hard problems in computer science: caching, naming, and off-by-1 errors. и лично предпочитаю использоватьat и пусть производительность уберет проверку, если она окажется ненужной.
0

Другие ответы являются полностью правильными, но может создать впечатление, что это хорошая идея для использованияat() при написании кода, который вы все еще будете отлаживать, так как это приведет к сообщению об ошибке. В общем случае это так, но это не относится к большинству распространенных компиляторов - gcc может быть настроен на выполнение (фатальных) проверок диапазона с помощьюперевод в режим отладки и нечто подобное, вероятно, можно сделать в Visual Studio.

0

Векторный метод C ++.at поэтому проверяют границы, когда элемент не существует в векторе, иout_of_range исключение брошено.

Когда используешь[] для вектора не выполняется проверка границ, поэтому, если элемент не существует, не генерируется исключение, и результатом является неопределенное поведение, такое как наличие случайных значений отсутствующих элементов в векторе.

С помощью[] лучше, чемat с точки зрения безопасности, однако, это потребует больше времени и влияет на производительность программы.

Похожие вопросы