0

As part of a larger project, I'm trying to create a simple template function that will take an array and a value, both of the same type, and fill the array with the value. I'm running into the error quoted below:

"specializing member '::Fill_With' requires 'template<>' syntax"

Below is the offending code fragment:

// Simple function to fill an array with a specified value.
template <class T> void Fill_With(T target_array, T value){
    int Array_Size = sizeof(target_array) / sizeof(T);
    for(int l = 0; l < Array_Size; ++l){
        target_array[l] = value;
    }
}

int array1[4] = {1,2,3,4}, k = 0;
Fill_With<int>(array1, k);

I've read numerous other forum posts on the error message, but haven't quite been able to figure out what I'm missing. I've read that I need to include a blank "template<>" header before the function declaration but that didn't seem to solve the issue. What am I doing wrong? Thanks!

1

1 Answer 1

0

Let's start by getting rid of the templates, as they make things more confusing. In the following, I replaced T with int.

void Fill_With(int target_array, int value){
    int Array_Size = sizeof(target_array) / sizeof(int);
    for(int l = 0; l < Array_Size; ++l){
        target_array[l] = value;
    }
}

Let's try it out! I pasted this into the Arduino IDE and compiled it. Here is the output:

sketch_aug01a/sketch_aug01a.ino: In function 'void Fill_With(int, int)':
sketch_aug01a:4: error: invalid types 'int[int]' for array subscript
         target_array[l] = value;
                       ^
exit status 1
invalid types 'int[int]' for array subscript

This is telling us that we're trying to subscript (that's the term for the [] syntax) a variable of type int with a variable of type int. In C++, a pointer to the start of an array has type int *, not int. Let's fix the type of target_array in the function signature:

void Fill_With(int *target_array, int value){

It compiles, but if you ran it you would quickly run into a bug:

  • When given an expression, the sizeof operator will return the number of bytes in the type of the expression. The type of the expression target_array is int *, so sizeof(target_array) == sizeof(int *). On 32-bit systems, sizeof(int *) == 32/8 == 4.
  • When given a type, the sizeof operator returns the number of bytes in the type. So sizeof(int) gives the number of bytes in an int, which is guaranteed to be at least 2 bytes (16 bits), but is usually 4 or 8 (it depends on the system).

Together, this means that Array_Size ends up being some small number like 0 or 1, regardless of the contents of target_array. To fix this, you can instead pass in the length of the array as a parameter:

void Fill_With(int *target_array, int array_size, int value){
    for(int l = 0; l < array_size; ++l){
        target_array[l] = value;
    }
}

int array1[4] = {1,2,3,4}, k = 0;
Fill_With(array1, 4, k);

Now you can put the templates back in:

template <class T> void Fill_With(T *target_array, int array_size, T value){
    for(int l = 0; l < array_size; ++l){
        target_array[l] = value;
    }
}

int array1[4] = {1,2,3,4}, k = 0;
Fill_With<int>(array1, 4, k);

By the way, C++ already has this function built in. It's called std::fill. Here's how to use it:

#include <algorithm>

int array1[4] = {1,2,3,4}, k = 0;
std::fill(array1, array1 + 4, k);
1
  • Thanks a ton for the detailed explanation. I'm still pretty noobish so the breakdown was great. FYI, after some tinkering and research, it does not appear that <algorithm> or std::fill are supported by Arduino, which is kind of a bummer. Thankfully I can just create the template function the correct way. Commented Aug 2, 2017 at 13:54

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.