I have tried all the 3 methods provide for linking error solution, but none of them worked ..
solution 1 is giving same linking errors.
solution 2and solution 3 is giving Error C2995 Function Template Has Already Been Defined error
I have tried method 3 with a template that is used in my current code project. It compiles and links fine, although I did not remove its implementation from the sln file (VS2017). You suggested that it has to be done though. Could you explain why it has to be removed and maybe also think of reasons why it works in my case?
From Solution Explorer, right-click on Something.cpp
Excluded From Build
Whenever you want to make changes to Something.cpp, you have to do the following:
Include Something.cpp in the build.
In Something.h, comment out #include "Something.cpp".
Build the solution (you may get linker errors).
In Something.h, uncomment #include "Something.cpp".
Exclude Something.cpp from the build.
Build the Solution.
Google C++ Style Guide[^] specifically says it's not a good idea to separate the template into a header and an inl file; with the exception of private implementation detail which must be contained in one and only one .cc file. Their justification is not clear from the Self-contained Headers section but becomes clear when you read the Forward Declarations section. The compiler may not be able to explicitly distinguish between the class and a void*. Thank you Google!
It fails link on last a.isValid for Method 3 on G++ 4.9.3 on cygwin:
undefined reference A<C>::isValid(string const*)
Note that the original declare is
A<Root>::isValid(string const*): bool
Don't know it's G++ problem or not.
Using Method 2 it passes, but I don't like include test.cc in main.cc though, because the template idea is to have multiple implementation of test.h. Method 2 has to change main.cc each time I have a new implementation.
Writing a normal header file, including it normally into the source file and instead of including header and source file into the program, just include the source file. When the source file is included, it automatically includes the header file.
I've read the Reason section and i understand that the compiler needs the definition of the class methods so it can create object of some type.I cannot understand why
the compiler has no such problem when it is dealing with ordinary class( not template).
Doesn't it need the definition of the methods and if so how it finds them?
I'm sorry if the question is stupid?
I cannot reccommend this article as it's not using the correct terminology.
The declaration of a function is just the prototype you normally see in the header file.
Sometimes you get the definition there too.
What you call the "implementation" is called the "definition" in the official vocabulary.
It follows that reading your article will cause problems to beginners who might get confused later if they dont know the official terminology.
The main reason I wanted to move template function definitions into a cpp file is so that I did not have to recompile a fairly massive project everytime I make a small change. In this case only method 1 works, but is not ideal as one has to define another function which constructs an object. What if you had different constructors? You would need to write a different function as well which is not ideal. How efficient is returning an object from a function? What if you wanted template class objects as member variables of another class?
In such a case I would suggest a 4th method: explicit template instantiation.
This method requires that you know all the template arguments you will be using before hand. Lets say you will be using an instance of TestTemp with int just do the following in any cpp file.
What if somebody else is going to continue a project of yours?
It will look like a spaghetti code to them and they'll write it from the beginning.
Also, if my company was about to agree on using any of those solutions, I would vote for the first and implement a
macro that does the job with an appropriate name such as CompileHelperClassName
The thing is that you don't only need to have a working code but also easy to read, robust and more.
How are you going to document that method? "Helper method in order to compile" ??
I would definitely go for the boost coding style, even without the hpp extension.
Otherwise the code is not clear on what it does and this should be a fundamental for all o us.
If you intend to include the template implementation, then don't call it ".cpp" - the form #include "file.cpp" "smells" badly...
Instead, rename it to "file. Indeed, a template implementation is much
Your helper implementation method is VERY problematic, since you must reference EVERY TYPE that will use the template. e.g. <int>, <string>, <short>, etc.
If someone attempt to use your template with some other type, they have no luck but modify your helper method.
(a small side-note: the helper method doesn't have to be implemented. it can even be just a forward-declaration to a method without an implementation that carries the template type in its signature. still, the above caveat applies.)
solution explained in "Method 1" has limitation. Yes, you are correct. We need to reference every object type in that temp function. In that situation, we can move to Method 2 and 3. The forward declarion also solve the problem.
It should be the compiler's job to do this for us. But it leaves us this problem. That means the compiler didn't finish its job!
But if I have to make a choice in these solutions, I choose the first one. It will keep the #include style look normal, and keep all files in the project list. No #include "something.cpp", no hidden something_impl.cpp file, only need to do a very little fix in the cpp file once for all. It's perfect! You've got my 5!!
Last Visit: 31-Dec-99 19:00 Last Update: 23-Feb-24 6:21