0

我正在做一个学校作业,我收到了这个奇怪的错误(我对 C++ 很陌生)。

我应该找到介于 1500 和 1900 之间的第一个值。当我第一次构建它时,一切正常,但是当我下次构建它时,我收到此错误:

error LNK2005: "bool __cdecl greaterThan1500SmallerThan1900(int)" (?greaterThan1500SmallerThan1900@@YA_NH@Z) already defined in Lab5.obj

如果我然后稍微更改代码(将谓词函数中的类型更改为双精度),它会再次构建一次。

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”文件。

4

3 回答 3

1

我还读过,当我使用模板时,我需要包含“.cpp”文件。

扔掉/否决/为我们确定告诉您这样做的资源。

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

从来#include没有.cpp

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

于 2013-01-18T18:13:36.703 回答
0

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

你必须从模板化的东西中分离出这个功能。这个函数应该在一个 cpp 文件中,而不是#include任何东西,而是添加到你的项目中。(似乎你已经在它被调用的地方有了它的声明——它应该保持不变)。

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

于 2013-01-18T18:21:07.433 回答
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);
}
于 2013-01-18T18:24:33.400 回答