0

I am using Visual Studio Community 2015 with the newest version of the Visual Micro Arduino Plugin, however I also tried compiling my code in the Arduino IDE. When compiling my code, there is the following error:

Compiling debug version of 'Autonomous_Car' for 'Arduino/Genuino Uno'
Autonomous_Car.cpp.o:In function `setup
Autonomous_Car.ino:undefined reference to `List<UpdateAble> List()
Autonomous_Car.ino:undefined reference to `List<UpdateAble> ~List() 
collect2.exe*:error: ld returned 1 exit status 
Error creating .elf

Some info

  • Adding #include "List.cpp" fixes the error, however this does not seem like valid C++.
  • The files do not lay in any sub-directory
  • In my Project Explorer both List.h and List.cpp are added to the project.
  • I also removed both files from the project, deleted them and added them again
  • I deleted the ́%AppData%\Local\Arduino15 ́ directory
  • I am fairly new to C++ and Arduino, there might be something obvious, what I just can't find

Autonomous_Car.ino

#include "List.h"
#include "UpdateAble.h"
void setup()
{
 List<UpdateAble>* myList = new List<UpdateAble>();
 myList->GetCount();
 delete myList;
}

List.h

#ifndef _LIST_h
#define _LIST_h
#if defined(ARDUINO) && ARDUINO >= 100
#include "arduino.h"
#else
#include "WProgram.h"
#endif
template <class T>
class List {
public:
 void Add(T &item);
 bool Contains(T &item);
 bool Remove(T &item);
 void Clear();
 int IndexOf(T &item);
 T* GetItem(int index);
 inline int GetCount() { return count; };
 inline int GetCapacity() { return capacity; };
 List();
 ~List();
private:
 void EnsureCapacity(int capacity);
 int count;
 int capacity;
 T** items;
};
#endif

List.cpp

#include "List.h"
// Constructor
template <class T>
List<T>::List() {
 List::capacity = 4;
 List::count = 0;
 List::items = new T*[List::capacity];
}
// Cleanup
template <class T>
List<T>::~List() {
 delete[] List::items;
}
template <class T>
void List<T>::EnsureCapacity(int capacity) {
 if (List::capacity < capacity) {
 // Kapazität verdoppeln
 List::capacity = List::capacity * 2;
 // Speicher für neues array reservieren
 T** newArray = new T*[List::capacity];
 // Array kopieren
 for (unsigned int i = 0; i < List::count; i++) {
 newArray[i] = List::items[i];
 }
 // Speicher von alten array freigeben und neues array zuweisen
 delete[] List::items;
 List::items = newArray;
 }
}
// Adds a new item to the list
template <class T>
void List<T>::Add(T &item) {
 List::EnsureCapacity(count + 1);
 List::items[count] = item;
 List::count++;
}
// Gets whether the list contains an item or not
template <class T>
bool List<T>::Contains(T &item) {
 return List::IndexOf(item) != -1;
}
template <class T>
bool List<T>::Remove(T &item) {
 int index = List::IndexOf(item);
 // If the item does not exist, we cannot remove it
 if (index == -1) return false;
 // Move every item behind our item one further
 for (int i = index + 1; i < List::count; i++) {
 List::items[i - 1] = List::items[i];
 }
 List::count--;
}
// Release the heap 
template <class T>
void List<T>::Clear() {
 for (int i = 0; i < List::count; i++) {
 delete List::items[i];
 }
 delete[] List::items;
}
// Gets an index of an item, -1 if not found
template <class T>
int List<T>::IndexOf(T &item) {
 for (int i = 0; i < List::count; i++) {
 if (List::items[i] == item) {
 return i;
 }
 }
 return -1;
}
template <class T>
T* List<T>::GetItem(int index) {
 if (index < List::count && index >= 0) {
 return List::items[index];
 }
 return 0;
}

I'd be very glad, if we can find the solution.

asked May 30, 2016 at 16:15

1 Answer 1

1

You're using a template class. A template class is a special corner case that breaks the "code in .cpp and definitions in .h files" rule.

Because it's a template it can't be pre-compiled - it needs to be specially compiled each time it is used, so that it can get the right values compiled in to the template place-holders, which are provided by the CU that has the template class included with it.

Because of that it is one of the rare cases where the code has to be in the header file.

For a full example you can take a look at my Average library which is a fully templated class.

answered May 30, 2016 at 16:22

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

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

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.