简体   繁体   中英

Include template implementation cpp file in header file and link confusion

I was reading an article An Idiot's Guide to C++ Templates - Part 2 and came to the Separation of Declaration and Implementation part.

Now I have three files with their content as follows:

sample.hpp

#ifndef SAMPLE_HPP
#define SAMPLE_HPP

template <typename T>
void displayValue(T tValue);

#include "sample.cpp"

#endif

sample.cpp

#include <iostream>
template <typename T>
void displayValue(T tValue){
  std::cout<<tValue<<std::endl;
}

main.cpp

#include "sample.hpp"
int main(void) {
  displayValue(20);
  displayValue(3.14);
  return 0;
}

According to the author,

your project/build now must not add Sample.CPP for compilation process

But instead, when I use:

g++ main.cpp sample.cpp -o main

It still works!

I think in such a case the object sample.o would still contain NO code about the template function displayValue , and in the main.o object, it contains. So in theory there are no errors. But why the author said must not ?

It is normal that you do not get any error. Because your definition and implementation are regarded as one file.

Better and usual C++ style is;

Header file (myClass.h): You should not include the implementation file (compiler will find it if there is any for you). Implementation (myClass.cpp): #include myClass.h

Main program (main.cpp) This will also need #include myClass.h

If you implement using this usual style you are expected to get a linkage error only because you shouldn't have separated the definition and implementation of template functions/classes.

Author might be referring to this.

Templates are partial definitions, so they can be qualified to be "partially" implemented in headers. In your case,

sample.hpp

#ifndef SAMPLE_HPP
#define SAMPLE_HPP

#include <iostream>
template <typename T>
void displayValue(T tValue){
  std::cout<<tValue<<std::endl;
}
#endif

main.cpp

#include "sample.hpp"
int main(void) {
  displayValue(20);
  displayValue(3.14);
  return 0;
}

This will work perfectly in any situation, even if you add the header in multiple locations(and is quite readable)

Or else you can still keep what you have done and be "theoretically correct" by including sample.cpp to other cpps that use the template. Which is a bit more work.

NB: This not the exact answer to the problem but a way to bypass everything including the problem.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM