С Новым годом! Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
Карта форума Темы раздела Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.58/55: Рейтинг темы: голосов - 55, средняя оценка - 4.58
3 / 3 / 2
Регистрация: 07.08.2018
Сообщений: 84
1

Неопределённая ссылка на функцию

08.10.2021, 23:41. Показов 10603. Ответов 7

Author24 — интернет-сервис помощи студентам
Доброго времени суток!

Имеется несколько файлов кода:

main.cpp
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
#include "functions.h" // Подключение файла с прототипами функций
                       // Глобальные константы RANDOM_RANGE, SAWTOOTH_HIGH и STAIRS_LENGTH
                       // Зарезервированы в нём
 
#include <iostream>  // Библиотека для работы с входным и выходным потоками
#include <cmath>     // Библиотека для работы с математическими функциями
#include <string>    // Библиотека для работы со строками
 
int main(){            // Главная исполняемая функция
    size_t size;       // Объявление переменной (беззнаковая, целая), в которой будет храниться размер массива
    cout << "Введите размер массива: "; // Вывод с помощью стандратного потока вывода сообщения о вводе размера массива
    cin >> size;       // Ввод с помощью стандартного потока ввода объявленного размера
    
    
    void (*TestFunc)(int*, const size_t, string&) = IncreasingSequenceGeneration;
 
    int *arr_int = new int [size];                      // Создание указателя на область в памяти для работы с целочисленным массивом
    string name = "";
    TestFunc(arr_int, size, name);
    delete[] arr_int;                                   // Высвобождение памяти из-под динамического массива целых чисел
    return 0;                                           // Программа возвращает 0 - корректное завершение работы
}                                                       // Конец главной функции
functions.h
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
#pragma once         // Для избежания проблемы двойного включения
 
#include <iostream>  // Библиотека для работы с входным и выходным потоками
#include <string>    // Библиотека для работы со строками
 
using namespace std;         // Пространство имён std для использования функций стандартной библиотеки
 
template <typename T>                                            // Шаблон для функции с типом данных T
void IncreasingSequenceGeneration (                              // Функция, генерирующая возрастающую последовательность, принимает:
                                    T* result                    // Указатель на массив типа T для работы
                                    , const size_t size          // Размер последовательности
                                    , string& function_name      // Строку для записи названия исполняемой функции
                                    );
functions.cpp
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
#include "functions.h"
 
template <typename T>                                            // Шаблон для функции с типом данных T
void IncreasingSequenceGeneration (                              // Функция, генерирующая возрастающую последовательность, принимает:
                                    T* result                    // Указатель на массив типа T для работы
                                    , const size_t size          // Размер последовательности
                                    , string& function_name      // Строку для записи названия исполняемой функции
                                    ){                           // Начало функции
    // .......
    for(size_t i = 0; i < size; ++i){                            // Цикл по i для перебора всего массива
        result[i] = i;                                           // Присваивание i-му элементу последовательности значения больше, чем i - 1
    }                                                            // Конец цикла по i
   
}                                                                // Конец функции, генерирующей возрастающую последовательность
Компилирую через g++ командой
Bash
1
g++ main.cpp functions.cpp -o prog
Или же пробовал так:
Bash
1
g++ *.cpp -o prog
И даже так:
Bash
1
g++ main.cpp functions.h functions.cpp -o prog
На что получаю ошибку:
Bash
1
main.cpp:(.text+0x43): неопределённая ссылка на «void IncreasingSequenceGeneration<int>(int*, unsigned long, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >&)»
Подозреваю, что проблема в 17 строчке файла main.cpp, но не могу понять, как её разрешить, при замене в main.cpp "functions.h" на "functions.cpp" всё нормально собирается.
0
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
08.10.2021, 23:41
Ответы с готовыми решениями:

Неопределенная ссылка
Всем привет :) Столкнулся с такой проблемой : Написал класс Contact и попробовал использовать...

Неопределённая ссылка
Здравствуйте! Сегодня решил я написать проект на OpenGL под Linux. Установил glut, компилятор gcc,...

неопределенная ссылка
Некомпилируется проект. Не могу понять где ошибка. prata-10-2-head.h #ifndef...

Неопределенная ссылка на `WinMain @ 16 '
учусь программировать в wxdev C++ по книге Шилдта. сделал все как написано а компилятор ругается не...

7
What a waste!
1610 / 1302 / 180
Регистрация: 21.04.2012
Сообщений: 2,733
08.10.2021, 23:51 2
ivan_proger, надо перенести определение шаблона функции (IncreasingSequenceGeneration) в заголовочный файл (из .cpp в .h)
1
3 / 3 / 2
Регистрация: 07.08.2018
Сообщений: 84
09.10.2021, 00:03  [ТС] 3
gray_fox, возможно, я чего-то не понимаю, но разве тогда не теряется концепция разнесения объявления и определения функции по разным файлам? Неужели их нельзя хранить раздельно?
0
19409 / 10028 / 2443
Регистрация: 30.01.2014
Сообщений: 17,678
09.10.2021, 00:10 4
Цитата Сообщение от ivan_proger Посмотреть сообщение
возможно, я чего-то не понимаю, но разве тогда не теряется концепция разнесения объявления и определения функции по разным файлам? Неужели их нельзя хранить раздельно?
Шаблон - это не функция. Это образец, по которому компилятор сделает функцию.
Так вот, чтобы это было возможно, в точке использования должен быть доступ к определению шаблона. Иначе как компилятор узнает каким образом делать для вас функцию?
1
3 / 3 / 2
Регистрация: 07.08.2018
Сообщений: 84
09.10.2021, 00:18  [ТС] 5
DrOffset, т.е. я правильно понимаю, что заголовочный файл с шаблоном по изложенным причинам должен содержать определение, а для известной функции допускается только объявление с последующим определением в другом файле с расширением .cpp?
0
19409 / 10028 / 2443
Регистрация: 30.01.2014
Сообщений: 17,678
09.10.2021, 00:22 6
Лучший ответ Сообщение было отмечено ivan_proger как решение

Решение

Цитата Сообщение от ivan_proger Посмотреть сообщение
но разве тогда не теряется концепция разнесения объявления и определения функции по разным файлам?
Хуже нет ситуации, когда некие "концепции" повторяются без понимания их сути.
Если кто-то вам говорит, что делать Х - хорошо, это совершенно не значит, что делать Х нужно всегда и везде.

Цитата Сообщение от ivan_proger Посмотреть сообщение
т.е. я правильно понимаю, что заголовочный файл с шаблоном по изложенным причинам должен содержать определение
В типовом случае - да. Но это опять же не аксиома.

Цитата Сообщение от ivan_proger Посмотреть сообщение
, а для известной функции допускается только объявление с последующим определением в другом файле с расширением .cpp?
Нет никакого "допускается только". Функция с полным определением может быть в заголовочном файле, если она inline или static, с соответствующими каждой из этих ситуаций эффектами.
0
3 / 3 / 2
Регистрация: 07.08.2018
Сообщений: 84
09.10.2021, 00:34  [ТС] 7
DrOffset, вы безусловно правы, спасибо!
0
What a waste!
1610 / 1302 / 180
Регистрация: 21.04.2012
Сообщений: 2,733
09.10.2021, 00:40 8
Лучший ответ Сообщение было отмечено ivan_proger как решение

Решение

Цитата Сообщение от ivan_proger Посмотреть сообщение
разве тогда не теряется концепция разнесения объявления и определения функции по разным файлам?
Возможно, но так устроен язык - если вы разместили определение шаблона в файле с исходным кодом, то только там вы и его и сможете использовать.

Т.к. шаблон по сути "макет" (класса или функции), то никакого кода из него самого по себе компилятор (в отличии от обычных классов или функций) при компиляции не генерирует - только когда вы этот шаблон используете.

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

Классичесий процесс сборки C++ (и C) кода таков, что компилятор сначала компилирует единицы трансляции (ваши .cpp) файлы раздельно, ничего не зная о других единицах трансляции, в объектные файлы, и только потом эти объектные файлы компануются в приложение или библиотеку. Поэтому, что бы инстациировать шаблон в разных единицах трансляции, его определение надо размещать в заголовочном файле.
1
09.10.2021, 00:40
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
09.10.2021, 00:40
Помогаю со студенческими работами здесь

Неопределенная ссылка на символ
Как только добавил 2 потока сразу начало ругать, что не так? #include &lt;iostream&gt; #include...

Неопределенная ссылка на деструктор
Здравствуйте! Какое-то время пользовался еклипсом, но пришлось от него отказаться в пользу утилит...

Неопределённая ссылка на «vtable for Animal»
Условие: Построить три класса (базовый и 3 потомка), описывающих некоторых хищных животных...

Неопределенная ссылка на конструктор(шаблоны)
Имеется класс SimpleMatrix его хедер: template&lt;typename T&gt; class SimpleMatrix { protected: ...

Неопределенная ссылка при многофайловой реализации шаблона
Здравствуйте уважаемые форумчане. И снова я что то делаю не так. Есть 3 файла main.cpp - сама...

Неопределенная ссылка при использовании шаблонного класса
в проекте 4 файла: CmakeLists.txt, main.cpp, list.h, list.cpp. CmakeLists.txt:...

Неопределённая ссылка на функцию
Если кратко, когда пытаюсь построить cmake-проект, то получаю следующее сообщение об ошибке: ...


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

Или воспользуйтесь поиском по форуму:
8
Ответ Создать тему
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2024, CyberForum.ru