Templated function being reported as “undefined reference” during compilation

人走茶凉 提交于 2019-12-02 20:32:30

问题


These are my files:

--------[ c.hpp ]--------

#ifndef _C
#define _C

#include<iostream>
class C
{
public:
    template<class CARTYPE> void call(CARTYPE& c);
};

#endif

--------[ c.cpp ]--------

#include "c.hpp"

template<class CARTYPE> void C::call(CARTYPE& c)
{
    //make use of c somewhere here
    std::cout<<"Car"<<std::endl;
}

--------[ v.cpp ]--------

class Merc
{};

--------[ main.cpp ]--------

#include "c.hpp"
#include "v.cpp"
//#include "c.cpp"

int main()
{
    Merc m; 
    C someCar;
    someCar.call(m);

}//main

I'm able to generate ".o" files for all the above files, with the command g++ -c main.cpp and g++ -c c.cpp and so on. But when I try linking the ".o" files with g++ -o car c.o main.o v.o I get this error:

main.o: In function `main':
main.cpp:(.text+0x17): undefined reference to `void C::call<Merc>(Merc&)'
collect2: ld returned 1 exit status

The error goes away when I uncomment the line #include "c.cpp" in main.cpp, but I feel it may be bad practice to include the cpp file this way. Am I doing this wrong? Is there a better way to cater to templated declarations while creating separate object files and linking them? p.s: I'm using the templated function in a much more complex class structure. What is shown here is just a small example for the sake of showing you the kind of error I'm facing.


回答1:


A way to solve this problem is to

a. remove '#include "c.hpp"' from c.cpp AND

b. include 'c.cpp' at the end of 'c.hpp' (strange sounding '#include "c.pp"')

This way the template definitions are availabe to each translation unit that includes 'c.hpp' without explicitly doing so in each .cpp file. This is called the 'inclusion model'




回答2:


I believe this is because when you compile c.cpp the compiler doesn't know it needs to generate code for C::call<Merc>(Merc&), and when you're compiling main.cpp it doesn't have the definition of C::call<T>(T&) from which to instantiate C::call<Merc>(Merc&).

Template definitions are essentially semantic macros, so much like the preprocessor's #define lexical macros they must be visible in the compilation units that use them.




回答3:


Essentially, you cannot have related template declarations and definitions in separate files in current C++. You should fully define class C in one file.



来源:https://stackoverflow.com/questions/3878884/templated-function-being-reported-as-undefined-reference-during-compilation

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!