#include<iostream>
#include<list>
#include<string>
using namespace std;
template<typename T>
T add(const T& lhs, const T& rhs){
return lhs + rhs;
}
template<typename T>
T mul(const T& lhs, const T& rhs){
return lhs * rhs;
}
template<typename T>
T accumulate(T (*comb)(const T&, const T&), const T& initial, list<T>& ls){
T ret(initial);
typedef typename list<T>::iterator Iterator;
for( Iterator i=ls.begin(); i!=ls.end(); i++ ){
ret = comb(ret, *i);
}
return ret;
}
int main(){
list<int> ls;
for( int i=0; i<10; i++){
ls.push_back(i+1);
}
cout << accumulate(add, 0, ls) << endl;
cout << accumulate(mul, 1, ls) << endl;
list<string> ls2;
ls2.push_back("a");
ls2.push_back("b");
ls2.push_back("c");
ls2.push_back("d");
ls2.push_back("e");
string empty("");
cout << accumulate(add, empty, ls2) << endl;
return 0;
}