LNK2005:已定义错误

时间:2013-01-18 18:10:00

标签: c++

我正在完成一项学校作业,我得到了这个奇怪的错误(我对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”文件,当我使用时模板。

3 个答案:

答案 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);
}