you can make fold templated and pass the same lambda you currently are
I don't quite follow - wouldn't I still need to somehow constrain the types passed to and from the lambda to types that match my input and accumulator?
You could instead take the vector by const reference and just change indices, or you could make it operate directly on the iterators.
This was actually my very first thought, but wanted to match a little more closely what a garbage-collected fold would do - probably worthwhile to actually code up both and compare!
Thanks for the tip about -02, I figured the tail recursion was at least some of the answer there.
// Fold a binary operation over a vectortemplate<typenameT>Tfold(std::vector<T>nums,Tacc,std::function<T(T,T)>func){intlength=nums.size();if(length==0){returnacc;}else{intnewAcc=func(acc,nums[0]);std::vector<T>newInput(nums.begin()+1,nums.end());returnfold(newInput,newAcc,func);}}// ..intmain(){// ..intresult=fold(nums,acc,[](intacc,intcurr){returnacc+curr;});// ..}
foldsum.cpp:12:3: note: template argument deduction/substitution failed:
foldsum.cpp:62:78: note: 'main()::<lambda(int, int)>' is not derived from 'std::function<T(T, T)>'
62 | int result = fold(nums, acc, [](int acc, int curr) { return acc + curr; });
This is probably telling me precisely what the problem is, but it's not clear to me.
Oh, that's interesting. You can fix it by specifying the template instantiation to use with fold<int>(......). I'm not sure exactly how the lambda ends up converting to a std::function. If you are okay with losing some information in the type signature you could also use a type parameter for the function type, making the function work with any 'callable' type.
Thanks a bunch!
I don't quite follow - wouldn't I still need to somehow constrain the types passed to and from the lambda to types that match my input and accumulator?
This was actually my very first thought, but wanted to match a little more closely what a garbage-collected fold would do - probably worthwhile to actually code up both and compare!
Thanks for the tip about
-02
, I figured the tail recursion was at least some of the answer there.I think this should work (don't have a compiler on hand to actually run it)
which I think you should be able to call exactly as you were doing.
That was what I had, this is the error:
This is probably telling me precisely what the problem is, but it's not clear to me.
Oh, that's interesting. You can fix it by specifying the template instantiation to use with
fold<int>(......)
. I'm not sure exactly how the lambda ends up converting to astd::function
. If you are okay with losing some information in the type signature you could also use a type parameter for the function type, making the function work with any 'callable' type.Ah, didn't think to try
fold<int>(......)
. I'm also no longer near a compiler, but I'll give both of those options a go later on.You can also add an additional template parameter BinaryOp like this:
See the code. And its also slightly faster since std::function has some overhead.
You can have a look at std::accumulate or std::reduce, they work fairly similar and are part of the STL ;-)
Happy coding
Ah, thanks! I like that better, I think - good to know about std:: function.
I had come across the STL options but this exercise was specifically to get there myself :)