пусть есть набор функций: Код (Text): uint32_t AddImpl(uint32_t ArgC, uint32_t* ArgV) { uint32_t res = 0; for(uint32_t t = 0; t < ArgC; t++) { res += ArgV[t]; } return res; } uint32_t SubImpl(uint32_t ArgC, uint32_t* ArgV) { uint32_t res = 0; for(uint32_t t = 0; t < ArgC; t++) { res -= ArgV[t]; } return res; } // и так далее как видно они различаются только одной маленькой операцией над переданным массивом, поэтом для уменьшения кода хотелось бы сделать единую функцию, которая принимала бы параметром допустим лямбда-выражение и применяла его аналогичным образом к переданному массиву... то есть примерно так: Код (Text): // вместо старого вызова: AddImpl(ArgC, ArgV); // использовать такой вызов: CommonImpl(ArgC, ArgV, [](uint32_t a, uint32_t b) -> uint32_t {return a + b;}); возможно ли так сделать с использованием лямбда выражений или необходимо писать N-отдельных функций и передавать в функцию указатель на них? и если возможно, то как оформить функцию CommonImpl и ее вызовы правильно?) заранее спасибо! ЗЫ забыл сказать, что использовать std::function и средства boost я не могу... в википедии пишут: не понимаю, что они имеют ввиду под "шаблонным типом", можете пояснить?
Вот такой вариант можно Код (Text): template<typename datatype, class callback> datatype process_data(size_t counter, datatype* data, callback& cb) { datatype result = 0; for (size_t i=0; i<counter; ++i) { cb(result, data[i]); } return result; } void testthis() { int values[3] = {1,2,3}; printf("%i\n",process_data(3, values, [](int& result, int x){ result -= x; })); printf("%i\n",process_data(3, values, [](int& result, int x){ result += x; })); }
А в конкретном примере можно и вот так Код (Text): void testthis() { int values[3] = {1,2,3}; int result =0; std::for_each(&values[0], &values[3], [&result](int x) { result += x; }); printf("%i",result); }
да... похоже, что подходит, надо будет только уточнить, не будет ли несколько функций в коде генерироваться для лямбд с одинаковыми прототипами... большое спасибо!
чего может быть проще? int foo_add(int a, int b){ return a + b; } int foo_sub(int a, int b){ return a - b; } int SubImpl(int ArgC, int* ArgV, int (*lambda)(int, int)) { int res = 0; for(int t = 0; t < ArgC; t++) { res = lambda(res, ArgV[t]); } return res; } CommonImpl(ArgC, ArgV, &foo_add); CommonImpl(ArgC, ArgV, &foo_sub); // иногда под функцию лучше тип объявить typedef int (*Lambda)(int, int); вот и все
Есть std::accumulate Мои пять копеек с итераторами. Код (Text): #include <algorithm> #include <vector> #include <iostream> #include <iterator> #include <numeric> template<typename itType, typename funcType> typename std::iterator_traits<itType>::value_type for_each2(itType first, itType second, funcType func) { typename std::iterator_traits<itType>::value_type result = 0; std::for_each(first, second, [&](decltype(result) a) { func(result, a);}); return result; } int main (int argc, char* argv[]) { std::vector<float> v; v.push_back(5); v.push_back(6.5f); v.push_back(1.5f); std::cout << for_each2(v.begin(), v.end(), [](float& result, float a) { return result += a; }) << std::endl; std::cout << std::accumulate(v.begin(), v.end(), 0.0f) << std::endl; }
с лямбдой красивее код, не надо создавать тонну функций, которые еще и могут заинлайниться оптимизацией, что мне совершенно не нужно...