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!
-
See this SO question: How to write a template function that takes an array and an int specifying array size001– 0012017年08月01日 20:48:23 +00:00Commented Aug 1, 2017 at 20:48
1 Answer 1
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 expressiontarget_array
isint *
, sosizeof(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. Sosizeof(int)
gives the number of bytes in anint
, 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);
-
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.spiteful_moose– spiteful_moose2017年08月02日 13:54:08 +00:00Commented Aug 2, 2017 at 13:54