1

I have a complex project, which consists of source files in various sub-directories which are compiled and archived into libXXX.a files. This compiled and linked well.

I now added the new file stdstrutils.cpp (together with its header file stdstrutils.h) to the sub-project in the "common" subdirectory.

This file contains a function with an ordinary template,

template<typename T> bool strToNum(const std::string sData, T *t);

and one with a variadic template,

template<typename... Args> std::string stdsprintf(const std::string sForma, Args... args);

(the declarations in the header file exactly match the functions in the c++-file) These functions are used by four c++-files in various of the sub-directories.

I added the line #include "stdstrutils.cpp" to the #includes in all the files that use the templated functions from stdstrutils, but i still get a lot of 'undefined reference to'-message from the linker. All concern the template-functions from stdstrutils.

The code of stdstrutils is definitely linked into the library libCommon.a: i checked this with a test-program - it compiled and linked without complaints, and executed as expected.

This is the link command from the make file:

 ~/utils/cgcc -fopenmp -std=c++11 -Wall -g  -o QHGMain \
  QHGMain.o Simulator.o SimParams.o EventChecker.o GridScrambler.o \
  -L ../populations -lPopulations \
  -L ../genes -lGenes \
  -L ../kernel -lKernel \
  -L ../modular -lModular \
  -L ../qmaps -lQMap \
  -L ../icosa -lIcosa \
  -L ../geoinfo -lGeoInfo \
  -L ../common -lCommon \
  -L ../io -lIO \
    -lz -lhdf5 -lm -lcrypto 

The callers of the functions from stdstrutils are in libCommon, libKernel as well as in the main directory (EventChecker.o).

Confusingly, there are other functions in libCommon which also have templates (and are called from different files), but they cause none of the 'undefined reference to'-messages.

So is there some rule about where to include the cpp-files (with the templated functions) which helps me avoid these messages?

user1479670
  • 1,145
  • 3
  • 10
  • 22
  • 2
    Template functions are typically implemented in header files (for this very reason). Or in a separate file, which is included at the end of header file. – Yksisarvinen Mar 03 '21 at 15:52
  • Related if not a duplicate: [https://stackoverflow.com/questions/495021/why-can-templates-only-be-implemented-in-the-header-file](https://stackoverflow.com/questions/495021/why-can-templates-only-be-implemented-in-the-header-file) – drescherjm Mar 03 '21 at 15:54
  • *"in a complex project?"* understand the issue with a smaller project. – Jarod42 Mar 03 '21 at 16:13
  • @Yksisarvinen; This does not seem to be necessary. I have template functions in similarly split h and cpp files, which do not cause this error. I have now #included stdstrutils.cpp at the end of stdstrutils.h, but it still reports undefined references. – user1479670 Mar 03 '21 at 16:16
  • @Jarod: i tried to build simpler projects, but so far none of them show the errors. – user1479670 Mar 03 '21 at 16:19
  • 1
    I had this kind of issues with template functions or template classes. I could split it in .h and .cpp files only when I had a friend function with this function being put in the cpp file. I recommend to copy the implementation of your function into your header file and include the header file rather than the cpp file (which is always a bit awkward and uncommon), – ManyQuestions Mar 03 '21 at 16:24
  • 1
    There's nothing in standard about dividing code into header files and .cpp files, every compiler will happily accept any file with valid code. That distinction is something created purely for humans, and purely for one goal - to let them easily separate things that must only have one copy in the program from things that may have multiple copies. If you destroy that convention and start including .cpp files, it *will* create problems in the future, when somebody else (or even you) will need to change that code and they will not know/remember about that convention break. – Yksisarvinen Mar 03 '21 at 16:27

0 Answers0