LNK2005:已定义错误

LNK2005: already defined error

本文关键字:错误 定义 LNK2005      更新时间:2023-10-16

我正在做一项学校作业,我遇到了这个奇怪的错误(我对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."文件。

我还读到,当我使用模板时,我需要包含".cpp"文件。

扔掉/投反对票/为我们确定告诉你这样做的资源。

它这样做是有充分理由的,但建议是错误的,它直接导致您遇到这个问题。

切勿将#include作为.cpp

放入模板定义的文件应该称为.ipp,而不是.cpp,这样您的IDE就不会将其与"常规"源文件混淆,并将其与项目的其余部分一起构建。这样的文件就像.h一样,只有#include d。

您的greaterThan1500SmallerThan1900不是模板,这就是为什么多次#include的主体是错误的(这就是为什么它必须链接一次(。

你必须把这个函数从模板化的东西中分离出来。这个函数应该在一个cpp文件中,而不是#included,而是添加到您的项目中。(您似乎已经在调用它的地方有了它的声明——它应该保持原样(。

对于模板,您可能会听从另一个答案的建议(重命名为*.ipp,将其#include从项目中删除(,但错误会在您这样做之前消失(将额外的仅模板源文件编译为空对象是无用的,但这不会造成伤害(。

如果您正在编写仅头库/模块,则使用#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);
}