Reputation: 986
I am working on a school assignment, and I get this strange error (I am quite new to C++).
I should find the first value between 1500 and 1900. When I build it the first time, everything is ok, but when I build it the next time, I get this error:
error LNK2005: "bool __cdecl greaterThan1500SmallerThan1900(int)" (?greaterThan1500SmallerThan1900@@YA_NH@Z) already defined in Lab5.obj
If I then change the code slightly (change the type in the predicate function to double) it builds again one time.
template<typename T>
T MyStlClass<T>::myFindIf(list<T> &theList) {
list<T>::iterator it = find_if(theList.begin(), theList.end(), greaterThan1500SmallerThan1900);
return *it;
}
bool greaterThan1500SmallerThan1900(int value){
return (value >= 1500 && value <= 1900);
}
I have read on this site that it is because that I include the ".cpp" file, but on the other hand, I have also read, that I need to include the ".cpp" file, when I am using templates.
Upvotes: 0
Views: 661
Reputation: 43024
If you are writing an header-only library/module, then use #pragma once
to avoid multiple inclusions, and mark the greaterThan1500SmallerThan1900
function inline
:
// MyStlClass.hpp
#prgma once
....
template<typename T>
T MyStlClass<T>::myFindIf(list<T> &theList) {
list<T>::iterator it = find_if(theList.begin(), theList.end(), greaterThan1500SmallerThan1900);
return *it;
}
// NOTE inline here:
inline bool greaterThan1500SmallerThan1900(int value){
return (value >= 1500 && value <= 1900);
}
Upvotes: 0
Reputation: 21517
Your greaterThan1500SmallerThan1900
is not a template, that's why it's wrong to #include
its body multiple times (and that's why it must be linked exactly once).
You have to split out this function from the templated stuff. This function should be in a cpp file never #include
d by anything, but added to your project. (It seems that you already have its declaration where it's called -- it should remain so).
As of the templates, you may heed another answer's advice (renaming to *.ipp
which you will #include
, removing from project), but the error will disappear before you do (compiling additional template-only source file to an empty object is useless, but it does not hurt).
Upvotes: 0
Reputation: 385395
I have also read, that I need to include the ".cpp" file, when I am using templates.
Throw away/downvote/identify for us the resource that told you to do that.
There is a good reason that it did so, but the recommendation was wrong and it has led you directly to this issue.
Never #include
a .cpp
.
The file you put template definitions in should be called something like .ipp
rather than .cpp
, so that then your IDE does not confuse it with a "regular" source file and build it with the rest of your project. Such a file is then, like a .h
, only #include
d.
Upvotes: 1