Using accumulate algorithm with a set of pairs

C

cesco

I have a set of pairs defined as follow:

set< pair<UserEquipment*, double> > numberOfFreqSlotsToAdd;

and I need to iterate through all the elements of the set in order
accumulate the second field of the pair (that is double). Is there any
way I can use the algorithm accumulate to accomplish this?
The following line of code

double unit = accumulate( numberOfFreqSlotsToAdd.begin(),
numberOfFreqSlotsToAdd.end(), 0.0);

of course, won't work. Can you suggest anything similar using the
algorithm accumulate?

Thanks
Francesco
 
T

TB

cesco sade:
I have a set of pairs defined as follow:

set< pair<UserEquipment*, double> > numberOfFreqSlotsToAdd;

and I need to iterate through all the elements of the set in order
accumulate the second field of the pair (that is double). Is there any
way I can use the algorithm accumulate to accomplish this?
The following line of code

double unit = accumulate( numberOfFreqSlotsToAdd.begin(),
numberOfFreqSlotsToAdd.end(), 0.0);

of course, won't work. Can you suggest anything similar using the
algorithm accumulate?

template <class InputIterator, class T, class BinaryOperation>
T accumulate (InputIterator first, InputIterator last, T init,
BinaryOperation binary_op);

Where foreach element:

init = binary_op(init,*first);
 
D

Daniel T.

"cesco said:
I have a set of pairs defined as follow:

set< pair<UserEquipment*, double> > numberOfFreqSlotsToAdd;

and I need to iterate through all the elements of the set in order
accumulate the second field of the pair (that is double). Is there any
way I can use the algorithm accumulate to accomplish this?
The following line of code

double unit = accumulate( numberOfFreqSlotsToAdd.begin(),
numberOfFreqSlotsToAdd.end(), 0.0);

of course, won't work. Can you suggest anything similar using the
algorithm accumulate?

I gave an answer to this in comp.learn.c-c++. Here I will give several
answers:

class Object { };

int main() {
typedef std::set<std::pair<Object*, double> > MySet;
MySet mySet;

double unit = accumulate(mySet.begin(), mySet.end(), 0.0,
plus_second<MySet::value_type>() );
}

The 'plus_second' functor is defined as follows:

template <typename Pair>
struct plus_second :
std::binary_function<typename Pair::second_type, Pair,
typename Pair::second_type>
{
typename Pair::second_type operator()(
const typename Pair::second_type& x, const Pair& y ) const
{
return x + y.second;
}
};

Or something slightly more generic:

class Object { };

int main() {
typedef std::set<std::pair<Object*, double> > MySet;
MySet mySet;

double unit = accumulate(mySet.begin(), mySet.end(), 0.0,
apply_to_second<std::plus<double>, MySet::value_type>());
}

Which uses something like (though I can't say I like the name much:)

template < typename Op, typename Pair >
class apply_to_second : std::binary_function<
typename Pair::second_type, Pair, typename Pair::second_type >
{
Op fn;
public:
typename Pair::second_type operator()( const typename
Pair::second_type& x, const Pair& y ) const
{
return fn( x, y.second );
}
};

Whether you use one of the above, the one I gave in the other group, or
the simplest one:

class Object { };

typedef std::set<std::pair<Object*, double> > MySet;

double fn(double x, const MySet::value_type& y)
{
return x + y.second;
}

int main()
{
MySet mySet;

double unit = accumulate(mySet.begin(), mySet.end(), 0.0,
ptr_fun(&fn));
}

Is up to you. I'll leave you with the XP mantra, "use the simplest thing
that works, refactor mercilessly."
 
M

Maxim Yegorushkin

cesco said:
I have a set of pairs defined as follow:

set< pair<UserEquipment*, double> > numberOfFreqSlotsToAdd;

and I need to iterate through all the elements of the set in order
accumulate the second field of the pair (that is double). Is there any
way I can use the algorithm accumulate to accomplish this?
The following line of code

double unit = accumulate( numberOfFreqSlotsToAdd.begin(),
numberOfFreqSlotsToAdd.end(), 0.0);

of course, won't work. Can you suggest anything similar using the
algorithm accumulate?

You can use an iterator that gets a first or second pair's member for
you.
http://groups.google.com/group/comp.lang.c++.moderated/msg/26b344960588d3ac
 
C

cesco

I'm facing a similar problem: I need to transform the set of pairs by
scaling the second element (that is a double) by a certain factor.

The following line of code:
// typedef set<pair<UserEquipment*, double> SetOfFsDouble;
// SetOfFsDouble numberOfFreqSlotsToAdd
transform(numberOfFreqSlotsToAdd.begin(), numberOfFreqSlotsToAdd.end(),
numberOfFreqSlotsToAdd.begin(), f_gx(bind2nd(std::multiplies<double>(),
unit), select2nd<SetOfFsDouble::value_type>()));

reports the following error:

1>c:\program files\microsoft visual studio 8\vc\include\algorithm(650)
: error C2679: binary '=' : no operator found which takes a right-hand
operand of type 'double' (or there is no acceptable conversion)
1> c:\program files\microsoft visual studio
8\vc\include\utility(55): could be 'std::pair<_Ty1,_Ty2>
&std::pair<_Ty1,_Ty2>::eek:perator =(const std::pair<_Ty1,_Ty2> &)'
1> with
1> [
1> _Ty1=UserEquipment *,
1> _Ty2=double
1> ]
1> while trying to match the argument list
'(std::pair<_Ty1,_Ty2>, double)'
1> with
1> [
1> _Ty1=UserEquipment *,
1> _Ty2=double
1> ]

while the following approach:

transform(numberOfFreqSlotsToAdd.begin(), numberOfFreqSlotsToAdd.end(),
numberOfFreqSlotsToAdd.begin(),
::make_pair(select1st<SetOfFsDouble::value_type>(),
(bind2nd(std::multiplies<double>(), unit),
select2nd<SetOfFsDouble::value_type>())) );

where I try to overcome the previous problem by creating a Pair to give
back to the set, reports the following error:

1>c:\program files\microsoft visual studio 8\vc\include\algorithm(650)
: error C2064: term does not evaluate to a function taking 1 arguments
1> c:\program files\microsoft visual studio
8\vc\include\algorithm(685) : see reference to function template
instantiation '_OutIt
std::_Transform<std::_Tree<_Traits>::iterator,_OutIt,_Fn1,std::_Iter_random_helper<_Cat1,_Cat2>::_Iter_random_cat>(_InIt,_InIt,_OutIt,_Fn1,_InOutItCat,std::_Range_checked_iterator_tag)'
being compiled
1> with
1> [
1>
_OutIt=std::_Tree<std::_Tset_traits<std::pair<UserEquipment
*,double>,SinrBasedWithoutPowerScaling::NumberOfFrequencySlotsComparison,std::allocator<std::pair<UserEquipment
*,double>>,false>>::iterator,
1> _Traits=std::_Tset_traits<std::pair<UserEquipment
*,double>,SinrBasedWithoutPowerScaling::NumberOfFrequencySlotsComparison,std::allocator<std::pair<UserEquipment
*,double>>,false>,
1> _Fn1=std::pair<select1st<std::pair<UserEquipment
*,double>>,select2nd<std::pair<UserEquipment *,double>>>,
1>
_Cat1=std::_Tree<std::_Tset_traits<std::pair<UserEquipment
*,double>,SinrBasedWithoutPowerScaling::NumberOfFrequencySlotsComparison,std::allocator<std::pair<UserEquipment
*,double>>,false>>::iterator::iterator_category,
1>
_Cat2=std::_Tree<std::_Tset_traits<std::pair<UserEquipment
*,double>,SinrBasedWithoutPowerScaling::NumberOfFrequencySlotsComparison,std::allocator<std::pair<UserEquipment
*,double>>,false>>::iterator::iterator_category,
1>
_InIt=std::_Tree<std::_Tset_traits<std::pair<UserEquipment
*,double>,SinrBasedWithoutPowerScaling::NumberOfFrequencySlotsComparison,std::allocator<std::pair<UserEquipment
*,double>>,false>>::iterator,
1>
_InOutItCat=std::_Iter_random_helper<std::_Tree<std::_Tset_traits<std::pair<UserEquipment
*,double>,SinrBasedWithoutPowerScaling::NumberOfFrequencySlotsComparison,std::allocator<std::pair<UserEquipment
*,double>>,false>>::iterator::iterator_category,std::_Tree<std::_Tset_traits<std::pair<UserEquipment
*,double>,SinrBasedWithoutPowerScaling::NumberOfFrequencySlotsComparison,std::allocator<std::pair<UserEquipment
*,double>>,false>>::iterator::iterator_category>::_Iter_random_cat
1> ]

Do you have any suggestion on how to solve this problem?
 
M

Maxim Yegorushkin

cesco said:
I'm facing a similar problem: I need to transform the set of pairs by
scaling the second element (that is a double) by a certain factor.

Use boost::transform_iterator for that.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,755
Messages
2,569,537
Members
45,020
Latest member
GenesisGai

Latest Threads

Top