DEV Community

Discussion on: Overly Functional C++: The Fold

 
deciduously profile image
Ben Lovy • Edited

That was what I had, this is the error:

// Fold a binary operation over a vector
template <typename T>
T fold(std::vector<T> nums, T acc, std::function<T(T, T)> func)
{
    int length = nums.size();
    if (length == 0)
    {
        return acc;
    }
    else
    {
        int newAcc = func(acc, nums[0]);
        std::vector<T> newInput(nums.begin() + 1, nums.end());
        return fold(newInput, newAcc, func);
    }
}

// ..

int main()
{
// ..
int result = fold(nums, acc, [](int acc, int curr) { return acc + 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.

Thread Thread
 
curtisfenner profile image
Curtis Fenner

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.

Thread Thread
 
deciduously profile image
Ben Lovy

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.

Thread Thread
 
markboer profile image
Mark Boer

You can also add an additional template parameter BinaryOp like this:

template <typename T, typename BinaryOperation>
T fold(std::vector<T> nums, T acc, BinaryOperation op)

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

Thread Thread
 
deciduously profile image
Ben Lovy • Edited

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 :)