问题
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