3

I am now writing a project about some sort algorithm and having some trouble with it. Here is my project structure. I make it simple that might save your time

//-------Sort.h------

#ifndef....
class Sort{
public:
    template <typename T>
    static bool foo(T* t_, ...);   //maybe more parameters
    ...                            //and maybe more functions
}
#endif

//--------foo.cpp-----

#include "Sort.h"

template<typename T>
bool Sort::foo(T* t_, ...){
    ...                             //function implementation
    return true;
}
template bool Sort::foo<int>(int*, ...);
template bool Sort::foo<char>(int*, ...);

However, I found it not so good. I have to specific template function at the end of each .cpp files. What's more, I cannot use these functions with custom classes(because I didn't specific the function with this class).

But if I write everything in Sort.hpp files, I cannot compile .hpp file into .a or .lib. What can I do to compile my project into library files While reducing duplication of work?

highly appreciate your help.

thanks

Oven.V
  • 67
  • 3
  • Yo, this is a very common mistake. See this question: https://stackoverflow.com/questions/495021/why-can-templates-only-be-implemented-in-the-header-file – smac89 May 31 '18 at 02:57
  • 3
    Possible duplicate of [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) – Code-Apprentice May 31 '18 at 02:57
  • 1
    If all your library consists of is templates, your library is a header-only library. The End. That's how C++ works. – Sam Varshavchik May 31 '18 at 03:05
  • @SamVarshavchik I'm a little confused, please tell me if I misunderstood. Accroding to your comment, if my library is made up of templates, it's not even good to compile into *.a. Instead, I should mix all the code in a *.hpp and give user the hpp file, while the implementation method is visible. If so, Is it defective compared to sone lib.a which make up with xx.o(one function in one cpp file and into a xx.o). Thank u, anyway – Oven.V May 31 '18 at 05:12
  • If your library is "made up of templates" there's nothing to compile. Templates, by themselves, is not compiled code that can be bundled into a library. End of story. That's how C++ templates work. There are many header-only libraries that consist only of header files, and not an actual library. – Sam Varshavchik May 31 '18 at 15:03

2 Answers2

0

Templates must be declared in a header file. This is just the way they work. Header files are not compiled as they are needed for #include directives in any code that uses your library. Boost is a great example of how a template library can be organized.

Code-Apprentice
  • 81,660
  • 23
  • 145
  • 268
0

It is not always clear whether it will work or not to separate implementation from declaration. I have tried to always keep the header and the cpp files for a class separate, but I got into linking errors quite often and depending on the compiler (or IDE I guess), the error messages might differ and it's frustrating. To avoid that, just mixe the implementation in the header file. Example

// header file

 ...   
template<typename T>
class Array
{
public:
~Array() { if (elems != nullptr) delete[] elems; }

Array() : logical_len(0), allocated_len(4), elems(new T[4]) {}

Array(std::initializer_list<T> lst) : logical_len(0),
    allocated_len(lst.size() * 2), elems(nullptr) {
    elems = new T[allocated_len];
    for (const T& x : lst)
        push_back(x);
}
...

At this point you have two options. You can compile the header file as a cpp file or just #include it in the main.cpp.

  • however i did try to mix all the code in a Sort.hpp file. but when i compile this hpp file, I did't get a "Sort.o" file. Instead, i get a "Sort.hpp.gch". Then I wonder if I continue using "ar crv libSort.a Sort.hpp.gch", Can libSort.a work exactly as other libX.a(make up of *.o) do? Thank You! – Oven.V May 31 '18 at 04:19
  • how are you compiling your project? IDE? g++? –  May 31 '18 at 08:29
  • g++ in CentOS. Now i include "*.cpp" in "Sort.h", and I can use #include "Sort.h" to make my functions work. But that's not the way i like it. – Oven.V May 31 '18 at 10:26
  • in you .h file instead of ending function with ";" just open curly brackets and write the code. then you can include your .h in g++ like "g++ -std=c++11 main.cpp myclass.h -o program.out", or "g++ -std=c++11 main.cpp -o program.out" but include the myclass.h in your main.cpp. get rid of the myclass.cpp file. –  Jun 01 '18 at 08:24