'Passing variable-length 2D array to functions using template

Here is an example of the problem I am having:

#include <stdio.h>
#include <iostream>

template<std::size_t U, std::size_t V>
void func2(int (&twoDArrayA)[U][V], const int shift){
    const int length = 1 << shift;
    int twoDArrayB[length][length]; //Successful
}

//template<std::size_t A> <-- Tried to solve the problem by adding this
void func1(const int shift){
    const int length = 1 << shift;
    int twoDArrayA[length][length]; //Failed

    func2(twoDArrayA,shift);
}

int main() {
    const int shift = 3;
    func1(shift);
}

Error message:

error: no matching function for call to 'func2(int [length][length], const int&)' template argument deduction/substitution failed: variable-sized array type 'int' is not a valid template argument

I thought it is because of the use of the template before the func2, so I tried to do the same thing on func1. The attempt of making the call to func1 fails instead. Error message:

error: no matching function for call to 'func1(const int&)' template argument deduction/substitution failed: couldn't deduce template parameter 'A'

Is there any way I can pass such an argument as twoDArrayA to func2?



Solution 1:[1]

func2 is failing to deduce the array size because it isn't known at compile time; length is being decided at runtime based on the argument you pass to func1. For the pass-by-reference to work with template arguments and deduction, you will need to have a 2D array with defined size at compile time, for example, int arr[8][8].

It looks like the code you're working on wants to decide the array size in func1 based on shift and then pass that array to func2. You might consider designing func2 to take an int** and then access it as you would a 2D array, based on the result of 1<<shift:

void func2(int** twoDArrayA, const int shift) {
  const int length = 1 << shift;
  int last_item = twoDArrayA[length-1][length-1]
}

You might also find some more helpful resources here!

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 jnichols2719