﻿# V2676\. MISRA\. The result of 'std::remove', 'std::remove\_if', 'std::unique' and 'empty' should be used\.

Диагностическое правило основано на руководстве [MISRA](https://misra.org.uk/) \(Motor Industry Software Reliability Association\) по разработке программного обеспечения\.

Правило актуально только для C\+\+\.

Вызов некоторых функций не имеет смысла, если результат их работы не используется\. Результат выполнения функций [`std::remove`](https://timsong-cpp.github.io/cppwp/n4950/alg.remove), [`std::remove_if`](https://timsong-cpp.github.io/cppwp/n4950/alg.remove), [`std::unique`](https://timsong-cpp.github.io/cppwp/n4950/alg.unique), [`std::empty`](https://timsong-cpp.github.io/cppwp/n4950/iterator.range#lib:empty(C&_c)) или функции\-члена [`empty`](https://timsong-cpp.github.io/cppwp/n4950/container.reqmts#lib:empty,containers) контейнера должен быть обязательно использован в коде\. Например, его можно передать в другую функцию, сохранить в переменную для дальнейшей логики или проверить в условии\.

Если возвращаемое значение этих функций никак не обрабатывается, код обычно не выполняет ожидаемое действие\. В таком случае состояние объектов или структура данных остаются неизменными, что приводит к некорректному поведению программы на следующих этапах её выполнения\.

Рассмотрим первый пример:

```cpp
void remove_odd(std::vector<int> &v)
{
  std::remove_if(v.begin(), v.end(),
                 [](auto item)
                 { 
                   return (item & 1) != 0;
                 });
}
```

Вызов функции `std::remove_if`, несмотря на её имя, не выполняет удаление элементов из вектора\. Он всего лишь перемещает их внутри вектора так, что возвращённый итератор указывает на первый элемент, удовлетворяющий предикату\. Диапазон элементов от этого итератора и до конца вектора предназначен в дальнейшем для удаления\.

Чтобы завершить операцию и удалить требуемые элементы из вектора, необходимо передать возвращённый итератор в функцию\-член [`std::vector<int>::erase`](https://timsong-cpp.github.io/cppwp/n4950/vector#lib:erase,vector):

```cpp
void remove_odd(std::vector<int> &v)
{
  auto it = std::remove_if(v.begin(), v.end(),
                           [](auto item)
                           {
                             return (item & 1) != 0;
                           });
  v.erase(it, v.end());
}
```

Рассмотрим второй пример:

```cpp
template <typename T>
void copy_elements(const std::vector<T> &src,
                         std::vector<T> &dst)
{
  dst.empty();
  dst.reserve(src.size());
  for (const T &elem : src)
  {
    dst.push_back(elem);
  }
}
```

Программист хотел очистить результирующий вектор перед его наполнением\. Однако вызов [`std::vector<T>::empty`](https://timsong-cpp.github.io/cppwp/n4950/container.reqmts#lib:empty,containers) не очищает контейнер, а всего лишь говорит о том, пустой он или нет\.

Чтобы очистить вектор, нужно воспользоваться функцией\-членом [`std::vector<T>::clear`](https://timsong-cpp.github.io/cppwp/n4950/sequence.reqmts#lib:clear,containers):

```cpp
template <typename T>
void copy_elements(const std::vector<T> &src,
                         std::vector<T> &dst)
{
  dst.clear();
  dst.reserve(src.size());
  for (const T &elem : src)
  {
    dst.push_back(elem);
  }
}
```