С наступающим Новым годом! Форум программистов, компьютерный форум, киберфорум
Наши страницы
С++ для начинающих
Войти
Регистрация
Восстановить пароль
 
 
Рейтинг 5.00/54: Рейтинг темы: голосов - 54, средняя оценка - 5.00
Ryder95
9 / 9 / 8
Регистрация: 24.10.2013
Сообщений: 216
1

Ошибка "undefined reference to"

26.09.2014, 02:12. Просмотров 10422. Ответов 34
Метки нет (Все метки)

Здравствуйте. Пишу набор функций, состоящих из двух файлов: fileio.h и fileio.cpp
Попытался подключить это к main.cpp, и использовать makefile, вылезла ошибка:
Код
main.cpp:(.text+0x2a): undefined reference to `int* finput<int>(int*, unsigned long*, char*, bool)'
Вот как выглядит заголовочный файл:
C++
1
2
3
4
5
6
7
8
9
10
11
#include <fstream>
using namespace std;
 
template <typename type>
type* finput(type*,unsigned long*,char*,bool f=0);
template <typename type>
type* finput(type*,unsigned long,char*,bool f=0);
 
template <typename type>
unsigned char foutput(type*,unsigned long,char*,bool f=0);
unsigned char foutput(char*,unsigned long,char*,bool f=0);
И файл с функциями:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
#include "fileio.h"
 
template <typename type>
type* finput(type* array,unsigned long* count,char* path,bool f)
//Функция чтения неизвестного количества однотипных данных из файлов
{
    if (f) //Если двоичный файл
    {
        ifstream file(path,ios::binary|ios::ate);//Открытие бинарного файла с конца
        if (file) //Если файл открылся
        {
            if (file.tellg()%sizeof(type)) return (type*)1; //Файл повреждён
            *count=file.tellg()/sizeof(type);//Определение количества элементов
            array=new type[*count];//Выделение памяти под элементы
            file.clear();
            file.seekg(0);//Перевод маркера в начало файла
            file.read((char*)array,*count*sizeof(type));//Чтение
            return array;
        }
        else return (type*)0; //Если файл не открылся
    }
    else //Если файл текстовый
    {
        ifstream file(path);//Открытие файла
        if (file)//Если файл открылся
        {
            *count=0;
            for (register type i;!file.eof();)
                if (file>>i) (*count)++;
                else
                    if (!file.eof()) return (type*)1;//Файл повреждён
            file.clear();
            file.seekg(0);
            array=new type[*count];
            for(register unsigned long i=0;i<*count;i++)
                file>>array[i];
            return array;
        }
        else return (type*)0;//Файл не открылся
    };
};
template <typename type>
type* finput(type* array,unsigned long count,char* path,bool f)
//Функция для чтения определённого количество однотипных данных из файлов
{
    if (f)//Если бинарный файл
    {
        ifstream file(path,ios::binary|ios::ate);
        if (file)//Если файл открылся
        {
            if (file.tellg()<count*sizeof(type)) return (type*)1;//Повреждённый файл
            file.clear();
            file.seekg(0);
            array=new type[count];
            file.read((char*)array,count*sizeof(type));//Чтение
            return array;
        }
        else return 0;//Если файл не открылся
    }
    else//Если текстовый файл
    {
        ifstream file(path);
        if (file)//Если файл открылся
        {
            array=new type[count];
            for(register unsigned long i=0;i<count;i++)
                if (!(file>>array[i]))//Файл повреждён
                {
                    delete []array;
                    return (type*)1;
                } ;
            return array;
        }
        else return (type*)0;//Если файл не открылся
    };
};
 
template <typename type>
unsigned char foutput(type* array,unsigned long count,char* path,bool f)
//Функция для записи в файл данных
{
    if (f) //Для бинарного файла
    {
        ofstream file(path,ios::binary);
        if (file)
        {
            file.write((char*)array,sizeof(type)*count);
            return 1;//Файл открылся и записан удачно
        }
        else return 0;//Файл не открылся
    }
    else //Для текстового файла
    {
        ofstream file(path);
        if (file)
        {
            for(register unsigned i=0;i<count;i++)
                file<<array[i]<<' ';
            return 1;//Файл открылся и записан удачно
        }
        else return 0;//Файл не открылся
    };
};
unsigned char foutput(char* array,unsigned long count,char* path,bool f)
//Функция для записи в файл данных типа char
{
    if (f) //Для бинарного файла
    {
        ofstream file(path,ios::binary);
        if (file)
        {
            file.write((char*)array,sizeof(char)*count);
            return 1;//Файл открылся и записан удачно
        }
        else return 0;//Файл не открылся
    }
    else //Для текстового файла
    {
        ofstream file(path);
        if (file)
        {
            for(register unsigned i=0;i<count;i++)
                file<<array[i];
            return 1;//Файл открылся и записан удачно
        }
        else return 0;//Файл не открылся
    };
};
Makefile написал вручную, выглядит так:
Код
all: main

main: main.o fileio.o
	g++ main.o fileio.o -o main

main.o: main.cpp
	g++ -c main.cpp

fileio.o: fileio.h fileio.cpp
	g++ -c fileio.h fileio.cpp
В чём моя ошибка?
0
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
26.09.2014, 02:12
Ответы с готовыми решениями:

Работа с шаблонами и ошибка "Undefined reference"
только приступил к изучению шаблонов и сразу куча вопросов и проблем прошу...

У меня ошибка - "undefined reference to `WinMain@16'"
#include &lt;cstring&gt; #include &lt;fstream&gt; #include &lt;stdio.h&gt; #include &lt;stdlib.h&gt;...

Ошибка: undefined reference to "omp_set_nested"
#include &quot;stdafx.h&quot; #include &quot;stdio.h&quot; #include &quot;omp.h&quot; int main() { ...

ошибка "undefined reference"
Изучаю С++ по книге Дейтелов. Работаю в Code Blocks Вот запнулся. Изучаю...

Ошибка "undefined reference to"
Не удается скомпилировать battery.h #ifndef BATTERY_H_INCLUDED #define...

34
MakItSim
18 / 18 / 14
Регистрация: 23.09.2014
Сообщений: 117
26.09.2014, 02:19 2
Шаблоны определяй прямо в .h файле. Иначе, какая функция, как ты думаешь, у тебя реализована в fileio.o? При компиляции fileio.o компилятор ничего о твоем main не знает, и каким параметром инстанцировать шаблон, соответственно, тоже.
0
Ryder95
9 / 9 / 8
Регистрация: 24.10.2013
Сообщений: 216
26.09.2014, 09:39  [ТС] 3
То есть мне нужно все функции, точнее их инструкции, сразу перенести в fileio.h? Дело в том, что у меня задача именно использовать два файла: fileio.h и fileio.cpp, где в .h будут только экземпляры, а в fileio.cpp уже будут только инструкции, причём в файле fileio.h не должно быть инклюда на fileio.cpp, то есть это нужно сделать с помощью makefile. Я два дня пытался понять, как в файл .o он соединяет два fileio.h и fileio.cpp, но не понял. Теперь вот он выводит такую ошибку. И если main.cpp ничего не знает о функции, вызываемой внутри, то как ему об этом сообщить?
0
MakItSim
18 / 18 / 14
Регистрация: 23.09.2014
Сообщений: 117
26.09.2014, 09:56 4
Цитата Сообщение от Ryder95 Посмотреть сообщение
То есть мне нужно все функции, точнее их инструкции, сразу перенести в fileio.h?
Не функции, а шаблоны. Функции может оставит на месте.
Цитата Сообщение от Ryder95 Посмотреть сообщение
Дело в том, что у меня задача именно использовать два файла: fileio.h и fileio.cpp, где в .h будут только экземпляры, а в fileio.cpp уже будут только инструкции
Тогда пиши обычными функциями.
0
taras atavin
4205 / 1768 / 211
Регистрация: 24.11.2009
Сообщений: 27,565
26.09.2014, 10:34 5
Сообщение undefined reference to значит, что компилятор функцию знает, но линкер не догадывается, где она валяется. Для исправления надо включить в проект файлы с телами всех используемых версий всех функций. Если функции библиотечные, то это делается подключением lib файлов, или со статическими библиотеками, или с библиотеками импорта в зависимости от того, валяются ли функции в lib, или в dll. В том числе это относится к своим библиотекам. В остальных случаях добавить в проект файлы с исходниками тел функций. Где именно они будут валяться - дело 128-е, но пихать их в голову - плохая идея.
0
MakItSim
18 / 18 / 14
Регистрация: 23.09.2014
Сообщений: 117
26.09.2014, 10:47 6
Цитата Сообщение от taras atavin Посмотреть сообщение
но пихать их в голову - плохая идея.
Как раз, шаблоны именно там и должны быть. Уже была тема, я помню:
Шаблоны. Ошибка компиляции: "Не удается сопоставить определение функции существующему объявлению"
Цитата Сообщение от taras atavin Посмотреть сообщение
Если функции библиотечные, то это делается подключением lib файлов, или со статическими библиотеками, или с библиотеками импорта в зависимости от того, валяются ли функции в lib, или в dll
Если ты явно не заиспользуешь функцию с нужными тебе типами, никаких функций из шаблона нигде не появится.
0
taras atavin
4205 / 1768 / 211
Регистрация: 24.11.2009
Сообщений: 27,565
26.09.2014, 10:49 7
Цитата Сообщение от MakItSim Посмотреть сообщение
Если ты явно не заиспользуешь функцию с нужными тебе типами, никаких функций из шаблона нигде не появится.
Ну как бы по факту линкер ругнулся, значит использованы.
0
MakItSim
18 / 18 / 14
Регистрация: 23.09.2014
Сообщений: 117
26.09.2014, 10:53 8
Цитата Сообщение от taras atavin Посмотреть сообщение
Ну как бы по факту линкер ругнулся, значит использованы.
Они использованы в main. А это другая единица трансляции. До мэйна, компилируется fileio.o - другая единица. В ней функции не использованы, поэтому шаблоны "не превратились" в функции. А main идет уже после и использует существующий объектник, в котором нет функций.
0
alsav22
5445 / 4840 / 831
Регистрация: 04.06.2011
Сообщений: 13,587
26.09.2014, 12:34 9
fileio.h
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
unsigned char foutput(char*,unsigned long,char*,bool f=0);
 
template <typename type>
type* finput(type* array,unsigned long* count,char* path,bool f)
//Функция чтения неизвестного количества однотипных данных из файлов
{
    if (f) //Если двоичный файл
    {
        ifstream file(path,ios::binary|ios::ate);//Открытие бинарного файла с конца
        if (file) //Если файл открылся
        {
            if (file.tellg()%sizeof(type)) return (type*)1; //Файл повреждён
            *count=file.tellg()/sizeof(type);//Определение количества элементов
            array=new type[*count];//Выделение памяти под элементы
            file.clear();
            file.seekg(0);//Перевод маркера в начало файла
            file.read((char*)array,*count*sizeof(type));//Чтение
            return array;
        }
        else return (type*)0; //Если файл не открылся
    }
    else //Если файл текстовый
    {
        ifstream file(path);//Открытие файла
        if (file)//Если файл открылся
        {
            *count=0;
            for (register type i;!file.eof();)
                if (file>>i) (*count)++;
                else
                    if (!file.eof()) return (type*)1;//Файл повреждён
            file.clear();
            file.seekg(0);
            array=new type[*count];
            for(register unsigned long i=0;i<*count;i++)
                file>>array[i];
            return array;
        }
        else return (type*)0;//Файл не открылся
    };
};
template <typename type>
type* finput(type* array,unsigned long count,char* path,bool f)
//Функция для чтения определённого количество однотипных данных из файлов
{
    if (f)//Если бинарный файл
    {
        ifstream file(path,ios::binary|ios::ate);
        if (file)//Если файл открылся
        {
            if (file.tellg()<count*sizeof(type)) return (type*)1;//Повреждённый файл
            file.clear();
            file.seekg(0);
            array=new type[count];
            file.read((char*)array,count*sizeof(type));//Чтение
            return array;
        }
        else return 0;//Если файл не открылся
    }
    else//Если текстовый файл
    {
        ifstream file(path);
        if (file)//Если файл открылся
        {
            array=new type[count];
            for(register unsigned long i=0;i<count;i++)
                if (!(file>>array[i]))//Файл повреждён
                {
                    delete []array;
                    return (type*)1;
                } ;
            return array;
        }
        else return (type*)0;//Если файл не открылся
    };
};
 
template <typename type>
unsigned char foutput(type* array,unsigned long count,char* path,bool f)
//Функция для записи в файл данных
{
    if (f) //Для бинарного файла
    {
        ofstream file(path,ios::binary);
        if (file)
        {
            file.write((char*)array,sizeof(type)*count);
            return 1;//Файл открылся и записан удачно
        }
        else return 0;//Файл не открылся
    }
    else //Для текстового файла
    {
        ofstream file(path);
        if (file)
        {
            for(register unsigned i=0;i<count;i++)
                file<<array[i]<<' ';
            return 1;//Файл открылся и записан удачно
        }
        else return 0;//Файл не открылся
    };
};
fileio.cpp
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
#include <fstream>
using namespace std;
 
unsigned char foutput(char* array,unsigned long count,char* path,bool f)
//Функция для записи в файл данных типа char
{
    if (f) //Для бинарного файла
    {
        ofstream file(path,ios::binary);
        if (file)
        {
            file.write((char*)array,sizeof(char)*count);
            return 1;//Файл открылся и записан удачно
        }
        else return 0;//Файл не открылся
    }
    else //Для текстового файла
    {
        ofstream file(path);
        if (file)
        {
            for(register unsigned i=0;i<count;i++)
                file<<array[i];
            return 1;//Файл открылся и записан удачно
        }
        else return 0;//Файл не открылся
    };
};
main
C++
1
2
3
4
5
6
7
8
9
#include <fstream>
#include "fileio.h"
using namespace std;
 
 
int main()
{
    ....
}
0
Ryder95
9 / 9 / 8
Регистрация: 24.10.2013
Сообщений: 216
26.09.2014, 17:23  [ТС] 10
То есть, как я понял, к шаблонам экземпляр сделать невозможно, верно?
0
taras atavin
4205 / 1768 / 211
Регистрация: 24.11.2009
Сообщений: 27,565
26.09.2014, 17:27 11
А что вообще такое экземпляр к шаблону? Экземпляры бывают у классов, а шаблоны сами по себе.
0
MakItSim
18 / 18 / 14
Регистрация: 23.09.2014
Сообщений: 117
26.09.2014, 17:29 12
Цитата Сообщение от Ryder95 Посмотреть сообщение
То есть, как я понял, к шаблонам экземпляр сделать невозможно
Экземпляр чего?
0
taras atavin
4205 / 1768 / 211
Регистрация: 24.11.2009
Сообщений: 27,565
26.09.2014, 17:43 13
Конечно можно. Экземпляры бывают у любых не абстрактных классов, шаблон абстрактного класса не имеет смысла.
0
Ryder95
9 / 9 / 8
Регистрация: 24.10.2013
Сообщений: 216
26.09.2014, 19:01  [ТС] 14
Тогда я совсем ничего не понимаю(
0
alsav22
5445 / 4840 / 831
Регистрация: 04.06.2011
Сообщений: 13,587
26.09.2014, 19:27 15
Цитата Сообщение от Ryder95 Посмотреть сообщение
То есть, как я понял, к шаблонам экземпляр сделать невозможно, верно?
Экземпляр шаблона создаётся, в частности, тогда, когда компилятор встречает вызов шаблонной функции. Это заставляет его сгенерировать экземпляр функции, используя определённый тип данных. Поэтому, в месте вызова шаблонной функции, для компилятора должна быть доступна реализация шаблона. Сам шаблон не является определением функции. Определением является экземпляр функции, сгенерированный по шаблону (экземпляр шаблона).
0
taras atavin
4205 / 1768 / 211
Регистрация: 24.11.2009
Сообщений: 27,565
26.09.2014, 19:39 16
Цитата Сообщение от alsav22 Посмотреть сообщение
Экземпляр шаблона создаётся, в частности, тогда, когда компилятор встречает вызов шаблонной функции.
Бред. При этом создаётся версия функции.
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
template <class TType> void swap(TTyper& x, TType &y)
{
 TType t;
 t=x;
 x=y;
 y=t;
}
int main()
{
 int x;
 int y;
 scanf("%i", x);
 scanf("%i", y);
 swap (x,y);
 sprintf("x=%i, y=%i", x, y);
 return 0;
}
. Здесь нет ни одного класса, соответственно нет и экземпляров классов.
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
class TVector
{
 double x, y, z;
 TVector ()
 {
  x=0.0;
  y=0.0;
  z=0.0;
 }
 TVector (const TVector &v)
 {
  x=v.x;
  y=v.y;
  z=v.z;
 }
 TVector operator + (TVector v)
 {
  TVector r;
  r.x=x+v.x;
  r.y=y+v.y;
  r.z=z+v.z;
  return r;
 }
TVector operator - (TVector v)
 {
  TVector r;
  r.x=x-v.x;
  r.y=y-v.y;
  r.z=z-v.z;
  return r;
 }
}
int main()
{
 TVector v1;
 TVector v2;
 return 0;
}
. Ни одной шаблонной функции нет, а экземпляров целых два.
0
alsav22
5445 / 4840 / 831
Регистрация: 04.06.2011
Сообщений: 13,587
26.09.2014, 20:07 17
Цитата Сообщение от taras atavin Посмотреть сообщение
Бред.
Тогда и Прата бредит.
0
Миниатюры
Ошибка "undefined reference to"  
taras atavin
4205 / 1768 / 211
Регистрация: 24.11.2009
Сообщений: 27,565
26.09.2014, 20:25 18
Экземпляр серийного автомобиля бывает, а экзеплляр штучной картины нет. Каждая из функций swap генерится с уникальным в пределах проекта кодом. Пусть исходный текст у них совпадает, но код разный и шаблон нужен именно для того, чтоб обеспечить эти различия, иначе достаточно написать
C++
1
2
3
4
5
6
7
void swap(void *x, void *y)
{
 void *t;
 t=x;
 x=y;
 y=t;
}
. Экземпляры объектов - совсем другое. Они различаются значениями членов, а не кодом операторов-челнов и функций-членов. Разные экземпляры автомобиля могут ехать по разным маршрутам, везти разный груз, у них могут различаться обороты двигателей, кто то перекачал, или не докачал колёса, но они остаются экземплярами. А когда у одного гидроуслитель руля, у другого электроусилитель руля, у третьего бортовые фрикционы и гусеничный движитель, у третьего шаровые колёса и так далее, а каждая машина уникальна, то уже экземплярами не воняет. Для разных типов - это именно версии. Экземпляр функции возможен, но если она много раз вызвана, тогда каждый экземпляр - отдельный кусок потока команд.

Добавлено через 44 секунды
Цитата Сообщение от alsav22 Посмотреть сообщение
Тогда и Прата бредит.
Прата? Или переводчик? Надо же и свою голову юзать.
0
alsav22
5445 / 4840 / 831
Регистрация: 04.06.2011
Сообщений: 13,587
26.09.2014, 20:26 19
Цитата Сообщение от taras atavin Посмотреть сообщение
Прата? Или переводчик?
Прата.
0
taras atavin
4205 / 1768 / 211
Регистрация: 24.11.2009
Сообщений: 27,565
26.09.2014, 20:35 20
Цитата Сообщение от alsav22 Посмотреть сообщение
Прата.
Уверен?

Добавлено через 7 минут
По сути здесь имеет место перегрузка, только не автор вручную прописывает, для каких именно типов следует перегрузить функцию, а компилятор определяет это автоматически. А где вообще вариант перегруженной функции для некоторого набора типов операторов назван экземпляром?
0
26.09.2014, 20:35
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
26.09.2014, 20:35

"undefined reference" при инклюде внешних классов/библиотек
Используется: Eclipse CDT, MinGW Немного сырцов: #ifndef STACK_H_...

Не собирается проект с шаблонным классом: "undefined reference"
Подскажите пожалуйста, не собирается проект. Пишет &quot;undefined reference to...

Работа с загаловочными файлами ("Undefined reference to")
Доброго времени суток. Не пойму почему компилятор Code Blocks выдаёт мне...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
20
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2018, vBulletin Solutions, Inc.
Рейтинг@Mail.ru