I have a very simple project with two sources and one header:
math_precision_io_test.cc
(containingmain
).main
contains the following lines:int retval = 0; retval = write_datum<float>(file1, &f2, "float"); retval = write_datum<double>(file2, &d2, "double");
math_precision_io.cc
, containing the functions to be used, includingtemplate<class T> int write_datum(std::ofstream & file, const T * datum, const char* descr) { static_assert(std::is_same<T, double>::value || std::is_same<T, float>::value || std::is_same<T, int>::value || std::is_same<T, char>::value, "write_datum is not defined on this class"); if (file.good()) { const size_t data_size = sizeof(T); file.write((char *) datum, data_size); if (descr != NULL) { std::cout << "Writing datum " << descr << std::endl; } return 0; } else { return 1; } }
math_precision_io.h
, included inmath_precision_io_test.cc
, with (among others) the declarationtemplate<class T> int write_datum(std::ofstream & file, const T * datum, const char* descr = NULL);
Both sources compile ok (objects are placed in dir obj/
).
When linking with
g++ -g -g3 -Wall -Wunused -Wuninitialized -Wextra -fmessage-length=0 -std=gnu++11 -o math_precision_io_test obj/math_precision_io_test.o obj/math_precision_io.o
I get
math_precision_io_test.cc:74: undefined reference to `int write_datum<float>(std::basic_ofstream<char, std::char_traits<char> >&, float const*, char const*)'
math_precision_io_test.cc:75: undefined reference to `int write_datum<double>(std::basic_ofstream<char, std::char_traits<char> >&, double const*, char const*)'
But if I only move the lines of function write_datum
from math_precision_io.cc
to math_precision_io_test.cc
, compile and link, the error disappears.
I cannot understand why.
What is the reason for the error, and how can it be fixed? (meaning keeping the function definition in math_precision_io.cc
and linking ok).
Note: The solution to the problem I found is indeed present in answers to the question linked to at the top. But the question itself is different, and one may not find the connection between the two right away. That is precisely what happened to me (otherwise, I would not ask the question).