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 ..
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
#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