Я пришел к следующему решению, вдохновленному функциями zip()
функциональных языков.Он компилируется и работает нормально, но, IMHO, это, вероятно, наиболее небезопасное использование пар итераторов begin()
& end()
, с которыми я когда-либо сталкивался, поэтому я не рекомендую использовать его в рабочем коде как есть.
#include <algorithm>
#include <cstddef>
#include <iterator>
#include <iostream>
#include <vector>
namespace {
// Iterator for pairs of items at same position in two sequences.
template<typename Lhs, typename Rhs>
class zipper
{
// Keep track of position in input sequences.
Lhs myLhs;
Rhs myRhs;
public:
// Minimal assumptions on iterator types `Lhs` and `Rhs`.
typedef std::input_iterator_tag iterator_category;
typedef std::pair<
typename std::iterator_traits<Lhs>::value_type,
typename std::iterator_traits<Rhs>::value_type
> value_type;
typedef value_type& reference;
typedef value_type* pointer;
typedef std::ptrdiff_t difference_type;
zipper ( Lhs lhs, Rhs rhs )
: myLhs(lhs), myRhs(rhs)
{}
value_type operator* () const {
return (value_type(*myLhs, *myRhs));
}
bool operator== ( const zipper<Lhs,Rhs>& other ) const {
return ((myLhs == other.myLhs) && (myRhs == other.myRhs));
}
bool operator!= ( const zipper<Lhs,Rhs>& other ) const {
return ((myLhs != other.myLhs) || (myRhs != other.myRhs));
}
zipper<Lhs,Rhs>& operator++ () {
++myLhs, ++myRhs; return (*this);
}
zipper<Lhs,Rhs> operator++ ( int ) {
const zipper<Lhs,Rhs> old(*this);
++(*this); return (old);
}
};
// Shorthand "a la" std::make_pair().
template<typename Lhs, typename Rhs>
zipper<Lhs,Rhs> make_zipper ( Lhs lhs, Rhs rhs )
{
return (zipper<Lhs,Rhs>(lhs, rhs));
}
// Check for equal items in a pair.
template<typename T> struct equal_pair
{
bool operator() ( const std::pair<T,T>& x ) const
{
return (x.first == x.second);
}
};
}
int main ( int, char ** )
{
// Test data.
const std::string lhs("abcddbca");
const std::string rhs("aabcdcca");
// Count how many pairs are equal.
const std::size_t equal_pairs = std::count_if(
make_zipper(lhs.begin(),rhs.begin()),
make_zipper(lhs.end() ,rhs.end() ), equal_pair<char>());
// Outputs "There are 4 equal pairs.".
std::cout
<< "There are " << equal_pairs << " equal pairs." << std::endl;
}