You could do it in two steps. First one is to find intersection, it could be done using set_intersection algorithm. Second step will be using transform algorithm to do math operations using supplied functor.
I've found that set_intersection
doesn't allow to supply access functor, so in the following code there is a lazy replacement for it. I wrote a sample functor that will do subtraction for you. I believe that you can easily write all other functors. Also you can write template function that will do the same as set_intersection
do, but with allowing to supply functor that will dereference iterator.
// sample functor for substruction
template<typename T1, typename T2>
struct sub
{
// it will be better to use const references, but then you'll not be able
// to use operator[], and should be use `find` instead
sub( std::map<T1, T2>& m1, std::map<T1, T2>& m2 ) : m1(m1), m2(m2) {}
std::pair<T1,T2> operator()( const T1& index )
{ return make_pair( index, m1[index]-m2[index] ); }
private:
std::map<T1, T2>& m1, & m2;
};
int main()
{
map<int, double> m1,m2;
m1[1] = 1.1;
m1[2] = 2.2;
m2[2] = 0.1;
m2[4] = 3.3;
vector<int> v; // here we will keep intersection indexes
// set_intersection replacement
// should be moved to stand alone function
map<int, double>::const_iterator begin1 = m1.begin();
map<int, double>::const_iterator begin2 = m2.begin();
for (; begin1 != m1.end() && begin2 != m2.end(); ) {
if ( begin1->first < begin2->first ) ++begin1;
else if (begin2->first < begin1->first) ++begin2;
else v.push_back( begin1->first ), ++begin1, ++begin2;
}
map<int, double> m3;
transform( v.begin(), v.end(), std::inserter(m3, m3.begin()), sub<int, double>( m1, m2 ) );
}