How can I pass a function as argument regardless of its return type in C++ ? (without using a template parameter for the passed function)

Viewed 135

I'm trying to make a map function. (recap: a map function is a function which applies a function to each items in a collection).

That sounds cool, but I want my map function to get as argument a function with any return type. However, I don't want to use native code snippets such as std::function.

With std::function
Note that even with void return type, it works with any input function regardless of its return type (the result I'm looking for)

#include <functional>
using namespace std;

template <typename T>
void map(function<void(T&)> f, T * collection, unsigned length)
{
    for(unsigned i = 0; i < length; i++)
        f(collection[i]);
}

An approach that doesn't work for non-void return type functions

template <typename T>
void map(void (*f)(T&), T * collection, unsigned length)
{
    for(unsigned i = 0; i < length; i++)
        f(collection[i]);
}

My solution

template <typename T, typename any>
void map(any (*f)(T&), T * collection, unsigned length)
{
    for(unsigned i = 0; i < length; i++)
        f(collection[i]);
}

Have you a solution that doesn't use a second template parameter ?
How should map be used regardless of its implementation (example):

#include "map.h"
#include <iostream>

void square(int& i){ i *= i; }

int main()
{
    int integers[] = { 5, 3, 2, 9 };

    map(&square, integers, 4);

    for(int i = 0; i < 4; i++)
        std::cout << integers[i] << std::endl;
    
    /*Output:
    25
     9
     4
    81
    */
}
1 Answers
#include <iostream>
#include <vector>
using namespace std;

void m(auto f, auto c)
{
   for(auto i : c)
      f(i);
}
 
int main() {
    m(
        [](int x) { cout << x << '\n'; },
        vector<int>{1, 2, 3});
    return 0;
}

Do you consider auto a template? You can make c (and i) mutable by taking them by reference.

Related