First use of template for array type

Windows 11, Visual Studio 2022, C++
This is my first attempt at a template. It will compare two arrays of type uint8_t, uint16_t, uint32_t, or uint64_t. And maybe others I have yet to considered.
Here is the h file:

1
2
3
4
5
6
7
8
9
10
11
12
13
 #pragma once
#include <stdint.h>

enum compare_enum
{
   data_error,
   equal_values,
   first_is_larger,
   second_is_larger
};

template<typename TYPE>
compare_enum compare_arrays( TYPE *a, TYPE *b, size_t compare_count );

Here is the code file:
1
2
3
4
5
6
7
8
9
// compare_arrays_template.cpp
// A function to compare arrays and detect differences

#include "compare_arrays_template.h"

compare_enum compare_arrays( uint8_t *a, uint8_t *b, size_t compare_count )
{
   return data_error;
}


And here is how it will be called in a console app that does little else
1
2
3
4
5
6
7
8
 
   cout << " compare two arrays " << endl;
   const size_t array_length = 8;
   uint8_t first[  array_length ] = { 1, 2, 3, 4, 9, 6, 7, 8 };
   uint8_t second[ array_length ] = { 1, 2, 3, 4, 5, 6, 7, 8 };
     
   compare_enum status;
   status = compare_arrays( first, second, array_length );


The code to do the compare and check the status will be added once this is at the point of compiling.
In the h file, VS squiggles “compare_arrays” and notes: “Function definition for compare_arrays not found.” That is not correct, because there it is.
The build error is:
1> compare_arrays.obj : error LNK2019: unresolved external symbol "enum compare_enum __cdecl compare_arrays<unsigned char>(unsigned char *,unsigned char *,unsigned int)" (??$compare_arrays@E@@YA?AW4compare_enum@@PAE0I@Z) referenced in function _main
1>E:\WX\compare_arrays\Debug\compare_arrays.exe : fatal error LNK1120: 1 unresolved externals

The error message appears to indicate it does not like the enum. But an enum is always a constant and its declared just above the function.
I tried a few variations of declaring the enum extern, but probably did not find the right formula.
Please advise as to what I am not recognizing.
Thank you for your time.
That's not how you do template functions. First, you have to put the entire implementation in the header file. Second, you don't declare the function as a template and then implement it for each type that you want to support. The whole point of templates is that the exact same function is applicable to multiple types.

Here's an example implementation:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
#pragma once
#include <cstddef>

enum compare_enum{
   data_error,
   equal_values,
   first_is_larger,
   second_is_larger
};

template <typename T>
compare_enum compare_arrays(const T *a, size_t a_size, const T *b, size_t b_size){
    if (a_size != b_size)
        return data_error;
    for (size_t i = 0; i < a_size; i++){
        if (a[i] < b[i])
            return second_is_larger;
        if (a[i] > b[i])
            return first_is_larger;
    }
    return equal_values;
}
The standard library already has std::lexicographical_compare
I did not get that concept from the explanatory page I found. It did not discuss the H versus the CPP file at all.

I modified the loop just a bit:

1
2
3
4
5
6
7
8
9
  compare_enum status = equal_values;
  while( (a[i] == b[i] ) && i < a_size )
      { i ++; }
   if( a[i] > b[i] ) 
      status = first_is_larger;
   else if( a[i] < b[i] ) 
      status = second_is_larger;

   return status;

The first version was:
 
  while( (a[i] == b[i] ) && i < a_size ) i ++;


But VS would not step though that loop. When the "i++" was extracted it would step through. I feel a bit better after walking through it with a couple of conditions set.

It worked the first time as written.
That std::lexicographical_compare looks like a major improvement. I will look at it. But I needed to write one of my own just for practice.

Thank you for your time and patience.
I don't know how the VS debugger works but perhaps you where stepping line-by-line and that was why putting i++ on a separate line made a difference?
Last edited on
Topic archived. No new replies allowed.