我正在完成一项学校作业,我得到了这个奇怪的错误(我对C ++很陌生)。
我应该找到介于1500和1900之间的第一个值。当我第一次构建它时,一切正常,但是当我下次构建它时,我收到此错误:
error LNK2005: "bool __cdecl greaterThan1500SmallerThan1900(int)" (?greaterThan1500SmallerThan1900@@YA_NH@Z) already defined in Lab5.obj
如果我稍微更改代码(将谓词函数中的类型更改为double),则会再次构建一次。
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);
}
我在这个网站上看过,因为我包含了“.cpp”文件,但另一方面,我也读过,我需要包含“.cpp”文件,当我使用时模板。
答案 0 :(得分:1)
我还读过,当我使用模板时,我需要包含“.cpp”文件。
抛弃/向下投票/识别告诉您这样做的资源。
有一个很好的理由,它是这样做的,但建议是错误的,它导致你直接这个问题。
从不#include
.cpp
。
您放置模板定义的文件应该被称为.ipp
而不是.cpp
,这样您的IDE就不会将它与“常规”源文件混淆并与其他文件一起构建你的项目。这样的文件就像.h
一样,仅 #include
d。
答案 1 :(得分:0)
您的greaterThan1500SmallerThan1900
不模板,这就是为什么#include
身体多次出错(这就是为什么必须被链接的原因恰好一次。)
你必须从模板化的东西中分离出这个函数。此函数应该在cpp文件中,而不是#include
d,而是添加到项目中。 (看来你已经有了声明所谓的 - 它应该保持这样)。
从模板开始,你可以注意另一个答案的建议(重命名为*.ipp
,你将#include
,从项目中删除),但错误将在你之前消失do(将另一个仅模板源文件编译为空对象是没用的,但它不会受到伤害)。
答案 2 :(得分:0)
如果您正在编写仅限标题的库/模块,请使用#pragma once
以避免多个包含,并标记greaterThan1500SmallerThan1900
函数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);
}