Раздельная компиляция с MinGW - PullRequest
2 голосов
/ 30 января 2012

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

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

Ответы [ 4 ]

2 голосов
/ 30 января 2012

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

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

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

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

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

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

1 голос
/ 01 февраля 2012

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

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

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

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

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

0 голосов
/ 19 февраля 2012

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

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

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

-m32 означает, что я собираю 32-битный код

-o - выходной файл (в моем примере это «тестовый» файл)

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

0 голосов
/ 31 января 2012

Я нашел эту статью полезной: шаблоны и заголовочные файлы

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...