Ответ 1
В С++ 14 стандартная библиотека будет содержать версию std::equal
, которая принимает две пары итераторов, похожие на ваш safe_equal
. То же самое для std::mismatch
и std::is_permutation
.
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;
}
Но есть ли безопасная альтернатива в стандартной библиотеке?
В С++ 14 стандартная библиотека будет содержать версию std::equal
, которая принимает две пары итераторов, похожие на ваш safe_equal
. То же самое для std::mismatch
и std::is_permutation
.
vector
имеет оператор ==, который сначала проверяет размер. В вашем примере просто используйте условие v==w
.
Я хотел такую функцию сам. Я не смог найти какие-либо средства в стандартной библиотеке.
Если вы готовы использовать boost. Boost.Range имеет то значение, которое, я думаю, является тем, что вы ищете http://www.boost.org/doc/libs/1_53_0/libs/range/doc/html/range/reference/algorithms/non_mutating/equal.html
У меня возникла такая же проблема и она была решена путем проверки размера вектора до равного.
std::vector< int > v( 100 );
std::vector< int > w( 10 );
bool same = (v.size() == w.size()) && std::equal( v.begin(), v.end(), w.begin() );
Вы также можете использовать std::lexicographical_compare
дважды, чтобы определить, меньше ли другая последовательность.