Есть ли безопасная альтернатива std:: equal?

std::equal() небезопасно, потому что функция не может знать, будет ли она превышать длину второго сравниваемого контейнера. То есть:

std::vector< int > v( 100 );
std::vector< int > w( 10 );
bool same = std::equal( v.begin(), v.end(), w.begin() );

... приведет к переполнению буфера для w.

Естественно, мы можем проверить эти вещи (v.size() == w.size()), но компиляторы, такие как Visual Studio 2010, все еще сообщают о самой функции как о небезопасной. И действительно, это небезопасно в некотором фундаментальном смысле: команда программистов разного уровня опыта в конце концов забудет сравнивать размеры.

Безопасную альтернативу легко реализовать.

template< typename Iter1, typename Iter2 >
bool equal_safe( Iter1 begin1, Iter1 end1, Iter2 begin2, Iter2 end2 )
{
    while( begin1 != end1 && begin2 != end2 )
    {
        if( *begin1 != *begin2 )
        {
            return false;
        }
        ++begin1;
        ++begin2;
    }
    return begin1 == end1 && begin2 == end2;
}

Но есть ли безопасная альтернатива в стандартной библиотеке?

Ответы

Ответ 1

В С++ 14 стандартная библиотека будет содержать версию std::equal, которая принимает две пары итераторов, похожие на ваш safe_equal. То же самое для std::mismatch и std::is_permutation.

Ответ 2

vector имеет оператор ==, который сначала проверяет размер. В вашем примере просто используйте условие v==w.

Ответ 4

У меня возникла такая же проблема и она была решена путем проверки размера вектора до равного.

  std::vector< int > v( 100 );
  std::vector< int > w( 10 );
  bool same = (v.size() == w.size()) && std::equal( v.begin(), v.end(), w.begin() );

Ответ 5

Вы также можете использовать std::lexicographical_compare дважды, чтобы определить, меньше ли другая последовательность.