Using templates in a library

Hi,

Given is a lightweight, writing only software serial library, where I want to implement a print function for arrays. I wrote a function, that does this, which takes the array and it's size as arguments, but I would like to get rid of having to pass the arrays size. I found, that this could be done by using templates, which I could make work in the main code, but fail to understand how to implement it in a library. This is what I have so far but get the error "invalid use of template-name 'WSerial' without an argument list" at compiling:

wserial.h

template <typename T, uint8_t size>

class WSerial {

 public:
  WSerial(uint8_t txPin);
  void begin(unsigned long speed);
  void write(uint8_t c);
//  void println(uint8_t *array, uint8_t n);
  void println(const T (&array)[size]);

 private:
  uint8_t txBitMask;
  volatile uint8_t* txPortRegister;
  uint16_t txDelay;
  void delay(void);

};

and the function definition in wserial.cpp

template <T, size> void WSerial<T, size>::println(const T (&array)[size]){
  for(uint8_t i = 0; i < size; i++){
    this->write(array[i]);
  }
  this->write('\r');
  this->write('\n');
}

and in the main code I just want to

#include <wserial.h>

WSerial wserial(7);

void setup() {
  uint8_t str[] = "Testing123";
  wserial.println(str);
}

Could anyone help me out?

You declared WSerial as a template class, but in your main code, you use the type without any template parameters.

It looks like you shouldn't be making the entire class a template, just make the relevant method a template function.

Template functions are not concrete functions, they are templates that the compiler can use to instantiate an actual function. It substitutes all template parameters at compile time, so the full definition of a template function must be available in the same translation unit. As a consequence, template functions cannot be defined in a separate CPP file, their definitions should be in the same header file as their declarations (unless you're using explicit template instantiation, which is not relevant here).

wserial.h


---



~~~
class WSerial {
public:
WSerial(uint8_t txPin);
void begin(unsigned long speed);
void write(uint8_t c);
template <class T, size_t size>
void println(const T color=#000000[/color][size]);

private:
    uint8_t txBitMask;
    volatile uint8_t* txPortRegister;
    uint16_t txDelay;
    void delaycolor=#000000[/color];
};

template <class T, size_t size>
void WSerial::println(const T color=#000000[/color][size]){
  for(auto &value : array)
    this->writecolor=#000000[/color]; // Is this correct? It converts every element from type T to uint8_t 
  this->writecolor=#000000[/color];
  this->writecolor=#000000[/color];
}
~~~

|

Pieter

Thank you Pieter, this is exactly what I was looking for!