Strange Linking Error

Maybe I am missing something obvious, I’m struggling trying to convert a little template class from a library I built for another project/platform. If I put the implementation of the three functions into the header, it compiles. If they are in the .cpp file, they will not.

Here is a stripped down version of my class that shows the errors:

ino:

#include "RingBuffer.h"

RingBuffer <int> ringBuffer(10);
//Timer timer(100, readSensor);

void setup(void)
{
  Serial.begin(9600);
}

void loop(void)
{
  static uint32_t lastSerialUpdateMillis = 0;
  if(millis() - lastSerialUpdateMillis > 1000)
  {
    Serial.print(ringBuffer.getAverage());
    lastSerialUpdateMillis = millis();
  }
  //timer.start();
}

void readSensor(void)
{
  //read sensor here
  ringBuffer.addValue(1.0f);
}

header:

#ifndef RINGBUFFER_H
#define RINGBUFFER_H

#include "Particle.h"

template < class Any_Type > class RingBuffer{
  public:
    RingBuffer(const size_t &size);
    void addValue(const Any_Type &value);
    Any_Type getAverage(void) const;
  private:
    Any_Type* myArray;
    size_t arraySize;
    uint32_t index = 0;
};

#endif

implementation:

#include "RingBuffer.h"

template < class Any_Type > RingBuffer < Any_Type >::RingBuffer(const size_t &size)
{
  arraySize = size;
  myArray = new Any_Type[size];
}

template < class Any_Type > void RingBuffer < Any_Type >::addValue(const Any_Type &value)
{
  myArray[index++] = value;
  index %= arraySize;
}

template < class Any_Type > Any_Type RingBuffer < Any_Type >::getAverage(void) const
{
  Any_Type sum = 0;
  for(int i = 0; i < arraySize; i++)
  {
    sum += myArray[i];
  }
  return (sum / arraySize);
}

error

Compiling code for photon

Including:
    RingBuffer.h
    CircularBuffer.ino
    RingBuffer.cpp
attempting to compile firmware 
Compile failed. Exiting.
../../../build/target/user/platform-6/libuser.a(CircularBuffer.o): In function `loop':
CircularBuffer.cpp:16: undefined reference to `RingBuffer<int>::getAverage() const'
../../../build/target/user/platform-6/libuser.a(CircularBuffer.o): In function `__static_initialization_and_destruction_0':
CircularBuffer.cpp:3: undefined reference to `RingBuffer<int>::RingBuffer(unsigned int const&)'
collect2: error: ld returned 1 exit status
make: *** [3f90c7d659bb94af3242458c08c6d4b27c51b71bfee3cf281671dbffbdb1.elf] Error 1

Admittedly, i was distracted by this post… and now regret spending any time on this!

C++ doesn’t permit splitting the implementation from the declaration for template types.

2 Likes

makes sense, it’s really not a class, it’s a template!

Thank you.

1 Like

Thanks for the help @woodwhcker!