2013-01-18 12 views
0

Я работаю над назначением школы, и я получаю эту странную ошибку (я довольно новичок в C++).LNK2005: уже определенная ошибка

Я должен найти первое значение между 1500 и 1900. Когда я строю его в первый раз, все нормально, но когда я построить его в следующий раз, я получаю эту ошибку:

error LNK2005: "bool __cdecl greaterThan1500SmallerThan1900(int)" ([email protected]@[email protected]) 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», когда я использую шаблоны.

+0

Пожалуйста, публикуйте код, кажется, что вы добавляете заголовочный файл, который уже определяет функцию 'bool largeThan1500SmallerThan1900 (int) {}' –

ответ

1

I have also read, that I need to include the ".cpp" file, when I am using templates.

Отбросьте/понизите/определите для нас ресурс, который сказал вам сделать это.

Существует веская причина, по которой он сделал это, но рекомендация была неправильной, и она привела вас непосредственно к этой проблеме.

Никогда #include a .cpp.

Файл вы кладете определение шаблонов в следует назвать что-то вроде .ipp, а не .cpp, так что тогда ваш IDE не путать с «регулярным» исходным файлом и построить его с остальной частью вашего проекта. Такой файл тогда, как и .h, только#include d.

+1

+1, нам нужен более большой шрифт для этого. (и «костер» приходит на ум в отношении таких бессмысленных ресурсов). – WhozCraig

+0

Я бы скорее дал определение в заголовке, чем предоставить еще один отдельный файл, который должен быть включен либо заголовком, либо конечным пользователем ... –

+0

@ Давид: Да, или это.Я не думаю, что когда-либо использовал файл '.ipp' (ну, был один случай, когда это был довольно большой шаблон шаблона), но мне удобно рекомендовать его для общего случая. Если ничего больше, он попадает в точку _not, в том числе '.cpp'_ более мощно, чем говорить« просто не включайте ничего ». –

0

Ваш greaterThan1500SmallerThan1900 является не шаблон, вот почему это неправильно #include его тело несколько раз (и именно поэтому он должен быть связан только один раз).

Вы должны отделить эту функцию от шаблонов. Эта функция должна быть в файле cpp никогда не #include d ничем, но добавлена ​​в ваш проект. (Кажется, у вас уже есть объявление , где оно называется - оно должно оставаться таким).

Как шаблонов, вы может прислушаться к совету другого ответа (в переименований *.ipp который вы будете #include, удаление из проекта), но ошибка исчезнет, ​​прежде чем вы (составление дополнительного шаблона только исходный файл в пустой объект бесполезен, но это не повредит).

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); 
} 
+0

Или просто не помещайте 'greatThan1500SmallerThan1900' во включенный файл. –

+0

@Lightness: Может быть, он хотел бы использовать модуль/библиотеку только для повторного использования заголовка. –

+0

Да, эта функция кажется действительно полезной для библиотеки –

Смежные вопросы