[lnkForumImage]
TotalShareware - Download Free Software

Confronta i prezzi di migliaia di prodotti.
Asp Forum
 Home | Login | Register | Search 


 

Forums >

comp.lang.c++

Applying a function to all elements of a container

(2b|!2b)==?

11/27/2008 3:32:00 PM

I want to be able to apply a function (cumulative sum) to all elements
of a container (a std::vector specifically, although it would be useful
to be able to do this with other containers too - say std::map)

I remember seing this done quite elegantly somewhere - dont remember if
the visitor design pattern was involved ...

Basically I have a struct that looks like this:

template<typename T>
struct MyDatedValue
{
MyDatedValue(DATE d, T val, T cv):date(d), value(val),cum_value(cv)
{}

~MyDatedValue(){}

DATE date;
T value;
T cum_value; //cumulative value
};

I have a vector of such values

typedef std::vector<MyDatedValue<double> > DoubleDatedValuesVector;


assuming I have the following code:


template<typename T>
static void Accumulate(const std::vector<MyDatedValue<T>& values);

void main(int argc, char* argv[])
{
DoubleDatedValuesVector values;

values.push_back(MyDatedValue<double>("1-Jan-80", 120, 0));
values.push_back(MyDatedValue<double>("2-Jan-80", 122, 0));
values.push_back(MyDatedValue<double>("3-Jan-80", 127, 0));

Accumulate<double>(values)
}


//A simplistic way of writing Accumulate() would be to iterate through
all of the members and add the values - is there a more elegant/generic
way of applying a function to STL container members (I think there is ..
bind() etc come to mind, but its been a while since I used that part
ofthe STL... hope some experienced STL users can refresh my memory ..
2 Answers

Michael DOUBEZ

11/27/2008 4:08:00 PM

0

(2b|!2b)==? a écrit :
> I want to be able to apply a function (cumulative sum) to all elements
> of a container (a std::vector specifically, although it would be useful
> to be able to do this with other containers too - say std::map)

You can use the std::acumulate algorithm:
vector<int> data;
int result=std::accumulate(data.begin(),data.end(),0);
//execute result=result+it; on all elements

You can even provide a custom binary function
double
result=std::accumulate(data.begin(),data.end(),1.0,std::multiplies<double>());
//execute result=functor(result,it); on all elements

> I remember seing this done quite elegantly somewhere - dont remember if
> the visitor design pattern was involved ...

The vistor pattern applies on a collection of polymorphic types.
It i not the case here.

> Basically I have a struct that looks like this:
>
> template<typename T>
> struct MyDatedValue
> {
> MyDatedValue(DATE d, T val, T cv):date(d), value(val),cum_value(cv)
> {}
>
> ~MyDatedValue(){}
>
> DATE date;
> T value;
> T cum_value; //cumulative value
> };
>
> I have a vector of such values
>
> typedef std::vector<MyDatedValue<double> > DoubleDatedValuesVector;
>
>
> assuming I have the following code:
>
>
> template<typename T>
> static void Accumulate(const std::vector<MyDatedValue<T>& values);
>
> void main(int argc, char* argv[])
> {
> DoubleDatedValuesVector values;
>
> values.push_back(MyDatedValue<double>("1-Jan-80", 120, 0));
> values.push_back(MyDatedValue<double>("2-Jan-80", 122, 0));
> values.push_back(MyDatedValue<double>("3-Jan-80", 127, 0));
>
> Accumulate<double>(values)
> }
>
>
> //A simplistic way of writing Accumulate() would be to iterate through
> all of the members and add the values - is there a more elegant/generic
> way of applying a function to STL container members (I think there is ..
> bind() etc come to mind, but its been a while since I used that part
> ofthe STL... hope some experienced STL users can refresh my memory ..

Define the operation T+MyDatedValue<T>:
T operator(const T&,const MyDatedValue<T>)
{
...
}

An you can directly use
T resule=std::accumulate(begin,end,T());

If that doesn't fit the semantic of MyDatedValue, define a binary
functor and pass it to accumulate.

--
Michael

r.grimm

11/29/2008 7:00:00 AM

0

Hallo,
> //A simplistic way of writing Accumulate() would be to iterate through
> all of the members and add the values - is there a more elegant/generic
> way of applying a function to STL container members (I think there is ..
> bind() etc come to mind, but its been a while since I used that part
> ofthe STL... hope some experienced STL users can refresh my memory ..
you can do it in an functional way with boost lambda.

#include <algorithm>
#include <numeric>
#include <iostream>
#include <vector>

#include <boost/lambda/lambda.hpp>

int main(){

boost::lambda::placeholder1_type Arg1;
boost::lambda::placeholder2_type Arg2;

std::vector <int> intVec;

for ( unsigned int i=1;i <= 10; ++i) intVec.push_back(i);
std::cout << "mult: " << std::accumulate( intVec.begin(), intVec.end
(),1,Arg1*Arg2) <<"\n";

}

Greetings Rainer