Станд. C++:: равный — объяснение позади не тестирования на 2 диапазона, имеющие равный размер?

Я просто написал некоторый код для тестирования поведения станд.:: равный, и ушел удивленный:

int main()
{
  try
  {
    std::list lst1;
    std::list lst2;

    if(!std::equal(lst1.begin(), lst1.end(), lst2.begin()))
      throw std::logic_error("Error: 2 empty lists should always be equal");

    lst2.push_back(5);

    if(std::equal(lst1.begin(), lst1.end(), lst2.begin()))
      throw std::logic_error("Error: comparing 2 lists where one is not empty should not be equal");
  }
  catch(std::exception& e)
  {
    std::cerr << e.what();
  }  
}

Вывод (удивление мне):

Error: comparing 2 lists where one is not empty should not be equal

Наблюдение: почему это станд.:: равный сначала не проверяет, имеют ли эти 2 контейнера то же size() ? Была ли законная причина?

7
задан sivabudh 16 March 2010 в 18:31
поделиться

4 ответа

Наблюдение: почему std :: equal не проверяет сначала, имеют ли 2 контейнера одинаковый размер ()? Была ли на то законная причина?

Как? Вы не передаете в функцию контейнеры, вы передаете итераторы . Функция не может узнать размер второго контейнера . Все, что он может сделать, это предположить добросовестно, что пользователь передал два допустимых диапазона контейнеров (т.е. что второй диапазон правильно указан как полуоткрытый интервал [ lst2.begin () , lst2). begin () - lst1.begin () + lst1.end () [) и действуйте соответственно.

12
ответ дан 6 December 2019 в 08:42
поделиться

Вы всегда можете написать свою собственную версию равного, которая эффективно делает то, что вы хотите:

template <class InputIterator1, class InputIterator2>
bool equalx(InputIterator1 first1, InputIterator1 last1,
            InputIterator2 first2, InputIterator2 last2)
{
  while ((first1 != last1) && (first2 != last2))
  {
    if (*first1 != *first2)   // or: if (!pred(*first1,*first2)), for pred version
      return false;
    ++first1; ++first2;
  }
  return (first1 == last1) && (first2 == last2);
}

Чтобы убедиться, что оба диапазона имеют одинаковое количество элементов, подпись должна включать конец второго диапазона.

4
ответ дан 6 December 2019 в 08:42
поделиться

Поскольку проверка размера может быть операцией O(n).

3
ответ дан 6 December 2019 в 08:42
поделиться

Это дает вам правильный ответ - вы сказали ему проверить, равны ли два контейнера в диапазоне lst1.begin() до lst1.end(). Вы все еще сравниваете два пустых списка, если речь идет о equal(). Если вы измените код для сравнения с lst2.begin() на lst2.end(), вы получите то, что ожидали.

2
ответ дан 6 December 2019 в 08:42
поделиться
Другие вопросы по тегам:

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