Search code examples
c++functionargumentsfunction-pointersvariadic-templates

Adding missing arguments to function pointer in another function


I have some functions which I would like to call using function pointer. They have different arguments and data types.

void processVec2(
    float a, 
    float b, 
    array<vector2> vec2_array, 
    int i, 
    int j)
{
/// some code here    
}
void processVec3(
    float a, 
    float b, 
    float c,
    float d, 
    array<vector3> vec3_array, 
    int i, 
    int j)
{
/// some code here    
}

I want to pass the function inside a loop lunction, and I want to add the loop iteration indices as argument before calling the function which was passed.

template<typename T, typename ... Args>
void loopFunction(
    int       iter,
    array<T>  array,
    void (*function)(Args)
    )
{
    // loop on iter
    for(int i = 0; i < iter; ++i)
    {
        // Loop on input array size
        int arraySize = array.size()
        for(int j = 0; j < arraySize, ++j)
        {
            function(args, i, j) // calling function. I want to pass some arguments and also i and j.
        }
    }
}

And this is where I want to set the function pointer. However, I don't know how to make it take its variables, and also I cannot set the loop indices variables inside the main function, so both the function pointer's arguments will miss two int.

// Main function
void main(
    float          a,
    float          b,
    float          c,
    float          d,
    int            vec2_iter,
    int            vec3_iter,
    array<vector2> vec2_array,
    array<vector3> vec3_array)
{
    // Call loopFunction, passing processVec2 as function pointer argument. I need to set the function's argument here too.
    loopFunction<vector2>(vec2_iter, vec2_array, &processVec2(a, b vec2_array));

    // Call loopFunction, passing processVec3 as function pointer argument. I need to set the function's argument here too.
    loopFunction<vector3>(vec3_iter, vec3_array, &processVec3(a, b, c, d, vec3_array));
}

for the loop function, I only need the _iter, _array, and the function pointer. However, I need to pass arguments from the main function to the function pointer, without explicitly passing them to the loop function.

Is this something possible ?


Solution

  • You need to change loopFunction to take the additional arguments you want to pass through, expand the parameter pack in the function pointer type and pass the arguments when you call the function pointer:

    template<typename T, typename ... Args>
    void loopFunction(
        int       iter,
        array<T>  array,
        void (*function)(Args..., int, int),
        Args... args
        )
    {
        // loop on iter
        for(int i = 0; i < iter; ++i)
        {
            // Loop on input array size
            int arraySize = array.size();
            for(int j = 0; j < arraySize; ++j)
            {
                function(args..., i, j);
            }
        }
    }
    

    Then in the calling function (note this shouldn't be called main) you can't pass the parameters when getting the function pointer and they need to be passed to loopFunction directly:

    // Call loopFunction, passing processVec2 as function pointer argument. I need to set the function's argument here too.
    loopFunction<vector2>(vec2_iter, vec2_array, &processVec2, a, b, vec2_array);
    
    // Call loopFunction, passing processVec3 as function pointer argument. I need to set the function's argument here too.
    loopFunction<vector3>(vec3_iter, vec3_array, &processVec3, a, b, c, d, vec3_array);
    

    It may be simpler to use lambdas instead:

    template<typename T, typename Function>
    void loopFunction(
        int       iter,
        array<T>  array,
        Function function
        )
    {
        // loop on iter
        for(int i = 0; i < iter; ++i)
        {
            // Loop on input array size
            int arraySize = array.size();
            for(int j = 0; j < arraySize; ++j)
            {
                function(i, j);
            }
        }
    }
    
    // Call loopFunction, passing processVec2 as function pointer argument. I need to set the function's argument here too.
    loopFunction<vector2>(vec2_iter, vec2_array, [&](int i, int j){ processVec2(a, b, vec2_array, i, j); });
    
    // Call loopFunction, passing processVec3 as function pointer argument. I need to set the function's argument here too.
    loopFunction<vector3>(vec3_iter, vec3_array, [&](int i, int j){ processVec3(a, b, c, d, vec3_array, i, j); });