There are some known linking issues when trying to separate a template class into header & implementation files. This page has several solutions, and so does this SO post, although neither address defining functions which involve the template though. In particular I am struggling to overload <<
into std::ostream
// include/valueStorer.h
#ifndef VALUE_STORER_H
#define VALUE_STORER_H
template <class T>
class ValueStorer
{
T value;
public:
ValueStorer(T);
void setValue(T);
T getValue();
};
#endif // #ifndef VALUE_STORER_H
// src/valueStorer.cpp
#include "valueStorer.h"
template <class T>
ValueStorer<T>::ValueStorer(T v)
{
value = v;
}
template <class T>
void ValueStorer<T>::setValue(T newValue)
{
value = newValue;
}
template <class T>
T ValueStorer<T>::getValue()
{
return value;
}
template class ValueStorer<double>;
// src/main.cpp
#include <iostream>
#include "ValueStorer.h"
int main()
{
ValueStorer<double> foo(3.14);
std::cout << "Value in foo is " << foo.getValue() << std::endl;
foo.setValue(4.2);
std::cout << "Value in foo is " << foo.getValue() << std::endl;
}
I compile the above with
g++ -c src/valueStorer.cpp -I include -o build/valueStorer.o
And main links and executes fine. I am unable to add an overload to operator<<
however:
// include/valueStorer.h (addition)
template <class T>
std::ostream &operator<< (std::ostream &, const ValueStorer<T> &);
// src/valueStorer.cpp (addition)
template <class T>
std::ostream &operator<< (std::ostream &os, const ValueStorer<T> &vs)
{
os << "Value is " << vs.getValue();
return os;
}
I can compile the implementation file fine but cannot link with main (which now calls <<
):
g++ src/main.cpp build/valueStorer.o -I include -o bin/program
main.cpp:(.text+0x3e): undefined reference to `std::ostream& operator<< <double>(std::ostream&, ValueStorer<double> const&)'
/usr/bin/ld: main.cpp:(.text+0x69): undefined reference to `std::ostream& operator<< <double>(std::ostream&, ValueStorer<double> const&)'
collect2: error: ld returned 1 exit status
Do I need to implement each of these overloads separately?