2012-01-30 2 views
2

Использование этого урока Makefile Я хочу создать простую программу с отдельной компиляцией. Основная проблема заключается в том, что IDE Eclpse Indigo C \ C++ (предполагаемый) или MinGW я не могу скомпилировать файлы. Ошибка, которую я получаю:Отдельная компиляция с помощью MinGW

undefined reference to double getAverage<int, 85u>(int (&) [85u])' 
undefined reference to int getMax<int, 85u>(int (&) [85u])' 
undefined reference to int getMin<int, 85u>(int (&) [85u])' 
undefined reference to void print<int, 85u>(int (&) [85u])' 
undefined reference to void sort<int, 85u>(int (&) [85u])' 
undefined reference to void print<int, 85u>(int (&) [85u])' 

Файл main.cpp это:

#include "Tools.h" 
#include <iostream> 
using namespace std; 

int main(int argc,char* argv[]) 
{ 
int numbers[] = {1,-2,7,14,5,6,16,8,-2,7,14,5,6,16,8,-2,7,14,5,6,16,8,-2,7,14,5,6,16,8,-2,7,14,5,6,16,8,-2,7,14,5,6,16,8,-2,7,14,5,6,16,8,-2,7,14,5,6,16,8,-2,7,14,5,6,16,8,-2,7,14,5,6,16,8,-2,7,14,5,6,16,8,-2,7,14,5,6,16,8}; 
cout <<"Average = "<< getAverage(numbers) << endl; 
cout <<"Max element = "<< getMax(numbers) << endl; 
cout <<"Minimal element = "<< getMin(numbers) << endl; 
print(numbers); 
sort(numbers); 
print(numbers); 
return 0; 
} 

и у меня есть Tools.h файл:

#ifndef TOOLS_H_ 
#define TOOLS_H_ 
#include <iostream> 
int getBigger(int numberOne,int numberTwo); 
template <typename T,size_t N> double getAverage(T (&numbers)[N]); 
template <typename T,size_t N> T getMax(T (&numbers)[N]); 
template <typename T,size_t N> T getMin(T (&numbers)[N]); 
/** 
* Implementing a simple sort method of big arrays 
*/ 
template <typename T,size_t N> void sort(T (&numbers)[N]); 
/** 
* Implementing a method for printing arrays 
*/ 
template <typename T,size_t N> void print(T (&numbers)[N]); 
#endif 
+2

Где ваши определения? Поскольку вы используете шаблоны, вы, вероятно, должны включать их в заголовок (.h). См. [Почему шаблоны могут быть реализованы только в файле заголовка?] (Http://stackoverflow.com/q/495021/20984). –

+0

Определения функций находятся в файле Tools.cpp. –

ответ

2

При компиляции Tools. cpp ваш компилятор не имеет представления о параметрах шаблона, которые вы использовали в main.cpp. Поэтому он не компилирует ничего, связанное с этими шаблонами.

Вам необходимо включить тезисы шаблонов из блока компиляции, который их использует. Файл Tools.cpp часто переименовывается в нечто вроде Tools.inl, чтобы указать, что это ни заголовочный файл, ни отдельный блок компиляции.

Компиляция блок «main.cpp» может выглядеть следующим образом:

#include "tools.h" 
#include "tools.inl" 

main() 
{ 
    int number[] = {1,2,3}; 
    getaverage(numbers); 
} 

Поскольку компилятор определяет требуемую специализацию он может генерировать код из файла реализации.

+0

Я изменяю расширение Tools.cpp на Tools.ini , но все еще существует проблема с неопределенной ссылкой на функции. –

+0

Но когда я определяю функции в файле заголовка, все в порядке. –

+0

Это нормально определить функции в файле заголовка, так как они являются встроенными функциями. Код генерируется, когда ваш код нуждается в реализации. Вам нужен только отдельный файл, если вы думаете, что заголовочный файл описывает интерфейс и не должен быть загроможден деталями реализации. – harper

0

Я нашел эту статью, которая будет полезна: templates and header files

Я объявил функцию в файле Tools.h и включить туда файл Tool.hpp и после этого я определил их в файле Tools.hpp.

1

В большинстве случаев ответ арфы подходит. Но для полноты также следует упомянуть явное создание шаблона.

Когда вы включаете реализацию в каждую единицу компиляции, ваши шаблонные классы и функции будут созданы и скомпилированы во всех них. Иногда это нежелательно. В основном это связано с ограничениями памяти во время компиляции и временем компиляции, если ваши классы шаблонов и функции очень сложны. Это становится очень реальной проблемой, когда вы или библиотеки, которые вы используете, сильно зависят от метапрограммирования шаблонов. Другая ситуация может заключаться в том, что реализация шаблонов может использоваться во многих единицах компиляции, и когда вы меняете реализацию, вам придется перекомпилировать все эти единицы компиляции.

Таким образом, решение в этих ситуациях должно включать заголовочный файл, такой как ваш tools.h, и иметь tools.cpp, реализуя шаблоны. Выгода заключается в том, что вы должны явно создавать шаблоны для всех аргументов шаблона, которые будут использоваться во всей вашей программе. Это достигается с помощью добавления следующих в tools.cpp:

template double getAverage<int,85>(int (&numbers)[85]); 

Примечание: Вы, очевидно, нужно сделать что-то о том, что «85», например, определив его в файле заголовка и использовать его по tools.cpp и main.cpp

+0

Да, я забыл упомянуть об этом. И я думаю, что это намеренный объект иметь «отдельный компиляцию», как его спрашивали. – harper

0

Я не пытался скомпилировать файлы .cpp и .c, но, может быть, мой пример поможет.

У меня была схожая проблема с составлением двух отдельных сборных файлов.s на MinGW со стандартной GCC компилятором и я достиг его следующим образом:

gcc -m32 -o test test.s hello.s 

-m32 означает, что я компиляции 32-битного кода

-о является выходной файл (который в моем примере является «тест "file)

test.s и hello.s являются моими исходными файлами. test.s является основным файлом, а hello.s имеет вспомогательную функцию. (О, говоря о том, что оба файла находятся в том же каталоге)

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