2014 dxdy logo

Научный форум dxdy

Математика, Физика, Computer Science, Machine Learning, LaTeX, Механика и Техника, Химия,
Биология и Медицина, Экономика и Финансовая Математика, Гуманитарные науки




Начать новую тему Ответить на тему На страницу 1, 2  След.
 
 Ошибка Unresolved external. c++ builder 10.4
Сообщение09.02.2023, 21:27 


24/01/22
61
main.cpp
код: [ скачать ] [ спрятать ]
Используется синтаксис C++
#pragma hdrstop
#pragma argsused

#ifdef _WIN32
#include <tchar.h>
#else
  typedef char _TCHAR;
  #define _tmain main
#endif

#include <stdio.h>
#include <iostream>
#include <conio.h>
#include "List.h"
int _tmain(int argc, _TCHAR* argv[])
{
        List<int> c;

        getch();
        return 0;
}
 


List.h
код: [ скачать ] [ спрятать ]
Используется синтаксис C++
//---------------------------------------------------------------------------

#ifndef ListH
#define ListH

#include<iostream>
template<typename T>
class List
{
        private:
    class _Node
        {
        public:
                _Node* m_next; //Указатель на следующий эл-т
                _Node* m_prev; //Указатель на предыдущий эл-т
                T m_data; //Значение эл-та

                _Node(T data = T{}, _Node* prev = nullptr, _Node* next = nullptr)
                        :m_data{ data }, m_prev{ prev }, m_next{ next }
                {
                }
        };

        _Node* m_first; //Указатель на первый эл-т списка
        _Node* m_last; //Указатель на последний эл-т списка
        int m_size;

    public:


        class Iterator
        {
        private:
                _Node* m_current;

        public:
                Iterator(_Node* first) : m_current{ first }
                {
                }

                T& operator++();
                T operator++(int);

                T& operator--();
                T operator--(int);

                bool  operator==(const Iterator& it);
                bool  operator!=(const Iterator& it);
                T& operator*();

        };

        List();
        ~List();


        friend std::ostream& operator<< (std::ostream& out, const List<T>& list);

        friend std::istream& operator>> (std::istream& in, List<T>& list);

        //Поместить эл-т в конец списка
        void pushBack(T el);
        //Убрать эл-т из конца списка
        void popBack();

        //Добавить эл-т в начало списка
        void pushFront(T el);
        //Удалить эл-т из начала списка
        void popFront();

        Iterator begin() const{ return m_first; }
        Iterator end() const{ return nullptr; }

        //Удаление i эл-та
        void remove(Iterator& i);
};
#endif

 


List.cpp
код: [ скачать ] [ спрятать ]
Используется синтаксис C++
//---------------------------------------------------------------------------

#pragma hdrstop

#include "List.h"
template<typename T>
List<T>::List()
        : m_size{ 0 }, m_first{ nullptr }, m_last{ nullptr }
{

}

template <typename T>
List<T>::~List()
{
        //Удаление эл-тов, пока список не станет пустым
        _Node* k{ };
        for (_Node* i = m_first; i != nullptr;)
        {
                k = i;
                i = i->m_next;
                delete k;
        }
}

#pragma package(smart_init)

 


Подскажите, что не так? Пишет: "[ilink32 Error] Error: Unresolved external 'List<int>::List<int>()' referenced from C:\USERS...", "Error: Unable to perform link"

 Профиль  
                  
 
 Re: Ошибка Unresolved external. c++ builder 10.4
Сообщение09.02.2023, 21:49 
Заслуженный участник


18/09/21
1764
В конце "List.cpp" добавить
Используется синтаксис C++
template class List<int>;

Или перенести конструктор и деструктор из "List.cpp" в "List.h".

 Профиль  
                  
 
 Re: Ошибка Unresolved external. c++ builder 10.4
Сообщение09.02.2023, 22:08 


24/01/22
61
zykov в сообщении #1580958 писал(а):
В конце "List.cpp" добавить
Используется синтаксис C++
template class List<int>;

Или перенести конструктор и деструктор из "List.cpp" в "List.h".

Спасибо, это помогло. Но почему так странно?

 Профиль  
                  
 
 Re: Ошибка Unresolved external. c++ builder 10.4
Сообщение09.02.2023, 22:21 
Заслуженный участник


18/09/21
1764
Ничего странного.
Это же шаблон (template).
Пока не создан instance, то для его функций нет кода.

Первый вариант явно создаёт instance для типа int прямо в List.cpp, с которым потом можно слинковаться.

Второй вариант - пернос всего в заголовок - делает доступным полное описание методов во всех исходниках, где включен этот заголовок. Там и линковаться не надо. Код будет сгенерирован при использовании обекта типа int (или какого другого).

 Профиль  
                  
 
 Re: Ошибка Unresolved external. c++ builder 10.4
Сообщение09.02.2023, 22:24 


24/01/22
61
zykov в сообщении #1580966 писал(а):
Ничего странного.
Это же шаблон (template).
Пока не создан instance, то для его функций нет кода.

Первый вариант явно создаёт instance для типа int прямо в List.cpp, с которым потом можно слинковаться.

Второй вариант - пернос всего в заголовок - делает доступным полное описание методов во всех исходниках, где включен этот заголовок. Там и линковаться не надо. Код будет сгенерирован при использовании обекта типа int (или какого другого).

До этого я писал в visual studio, и ничего такого не требовалось.

-- 09.02.2023, 22:27 --

Погодите, разве это не костыль? Смысл же шаблона в том, что я не знаю какой будет использоваться тип данных, а тут я явно указываю, что это - int.

-- 09.02.2023, 22:32 --

Я дописал operator >> и operator <<. Выдается та же самая ошибка
[ilink32 Error] Error: Unresolved external 'operator >>(std::basic_istream<char, std::char_traits<char> >&, List<int>&)' referenced from C:\USERS
Перенес все из List.cpp в List.h. Не помогло. В visual studio все работает нормально.

 Профиль  
                  
 
 Re: Ошибка Unresolved external. c++ builder 10.4
Сообщение09.02.2023, 22:32 
Заслуженный участник


18/09/21
1764
Нет, это фича языка.
Хотите для любого типа - пишите всё в заголовке. Плата за это, каждый раз это должно заново компилироваться.
Хотите скомпилировать один раз и потом линковать, делайте Explicit instantiation.
Никто не мешает сделать для нескольких типов вроде:
Используется синтаксис C++
template class List<int>;
template class List<double>;
template class List<float>;

 Профиль  
                  
 
 Re: Ошибка Unresolved external. c++ builder 10.4
Сообщение09.02.2023, 22:34 


24/01/22
61
А если пользователь захочет создать список со своим типом данных?

 Профиль  
                  
 
 Re: Ошибка Unresolved external. c++ builder 10.4
Сообщение09.02.2023, 22:37 
Заслуженный участник


18/09/21
1764
Точно так же можно сделать:
Используется синтаксис C++
template class List<TMyType>;
Только нужно туда заголовок подключить с этим своим типом.

 Профиль  
                  
 
 Re: Ошибка Unresolved external. c++ builder 10.4
Сообщение10.02.2023, 18:37 
Аватара пользователя


28/10/21
100
XeuTeP_KoLLIu в сообщении #1580967 писал(а):
До этого я писал в visual studio, и ничего такого не требовалось.


Вы что-то выдумываете. Это требуется всегда и везде по совершенно очевидным и естественным причинам: шаблон - это фактически усовершенствованный "макрос".

XeuTeP_KoLLIu в сообщении #1580967 писал(а):
Погодите, разве это не костыль? Смысл же шаблона в том, что я не знаю какой будет использоваться тип данных, а тут я явно указываю, что это - int.


Совершенно верно. В таком применении это - костыль и делать так не нужно.

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

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

XeuTeP_KoLLIu в сообщении #1580967 писал(а):
Я дописал operator >> и operator <<. Выдается та же самая ошибка


Я не вижу этого в приведенном на данный момент коде, но мой дар ясновидения подсказывает мне, что это уже совсем другая ошибка. Вы на самом деле определили не тот оператор, который объявили, потому и получаете ошибки линковки. Это очень распространённая ошибка при определении "друзей" для шаблонных классов.

Простейший вариант решения этой проблемы: поместите определения этих операторов прямо в класс, прямо туда где вы их объявили. Более того (не вдаваясь в детали): для того варианта объявления friend-функции шаблона класса, который вы использовали в вашем коде, в С++ невозможно предоставить определение за пределами определения шаблона класса - для этого в С++ просто не существует синтаксиса.

 Профиль  
                  
 
 Re: Ошибка Unresolved external. c++ builder 10.4
Сообщение10.02.2023, 20:25 


24/01/22
61
TheRuinedMap в сообщении #1581042 писал(а):
XeuTeP_KoLLIu в сообщении #1580967 писал(а):
До этого я писал в visual studio, и ничего такого не требовалось.


Вы что-то выдумываете. Это требуется всегда и везде по совершенно очевидным и естественным причинам: шаблон - это фактически усовершенствованный "макрос".

XeuTeP_KoLLIu в сообщении #1580967 писал(а):
Погодите, разве это не костыль? Смысл же шаблона в том, что я не знаю какой будет использоваться тип данных, а тут я явно указываю, что это - int.


Совершенно верно. В таком применении это - костыль и делать так не нужно.

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

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

XeuTeP_KoLLIu в сообщении #1580967 писал(а):
Я дописал operator >> и operator <<. Выдается та же самая ошибка


Я не вижу этого в приведенном на данный момент коде, но мой дар ясновидения подсказывает мне, что это уже совсем другая ошибка. Вы на самом деле определили не тот оператор, который объявили, потому и получаете ошибки линковки. Это очень распространённая ошибка при определении "друзей" для шаблонных классов.

Простейший вариант решения этой проблемы: поместите определения этих операторов прямо в класс, прямо туда где вы их объявили. Более того (не вдаваясь в детали): для того варианта объявления friend-функции шаблона класса, который вы использовали в вашем коде, в С++ невозможно предоставить определение за пределами определения шаблона класса - для этого в С++ просто не существует синтаксиса.

Спасибо. Это помогло. Только я все равно не понимаю почему все работает именно так.

 Профиль  
                  
 
 Re: Ошибка Unresolved external. c++ builder 10.4
Сообщение10.02.2023, 20:36 
Заслуженный участник
Аватара пользователя


01/08/06
3136
Уфа
Я почти не знаю C++. Но, помнится, краем уха где-то слышал байку, что есть компиляторы, умеющие специализировать шаблон в рантайме. Якобы в библиотеку рантайма специально для этого внедрялся какой-то урезанный компилятор.
Хотя, возможно, я что-то напутал. Возможно, это было про другой язык.

 Профиль  
                  
 
 Re: Ошибка Unresolved external. c++ builder 10.4
Сообщение10.02.2023, 20:51 
Заслуженный участник


18/09/21
1764
worm2
Есть такая штука - JIT (just-in-time) компиляция.
Видел как-то на Java такое исследовали (не знаю, есть ли где-то в production).
Но там обычно речь про оптимизацию с учётом реальной статисики исполнения кода (для текущего профиля данных).

 Профиль  
                  
 
 Re: Ошибка Unresolved external. c++ builder 10.4
Сообщение10.02.2023, 20:55 
Аватара пользователя


28/10/21
100
XeuTeP_KoLLIu в сообщении #1581053 писал(а):
Только я все равно не понимаю почему все работает именно так.


О чем именно речь? О шаблонах в целом? Или о тонкостях определения дружественных функций для шаблонных классов?

-- 10.02.2023, 10:00 --

worm2 в сообщении #1581055 писал(а):
Но, помнится, краем уха где-то слышал байку, что есть компиляторы, умеющие специализировать шаблон в рантайме.


Это что-то невероятное.

Были компиляторы, которые реализовывали другой подход к инстанцированию шаблонов во время компиляции. Вместо того, чтобы плодить множественные копии одного и того же кода, а потом вычищать лишние копии на стадии линковки (как поступают все современные реализации), они использовали двухпроходный подход: первым проходом они собирали информацию о том, какие специализации шаблонов используются в программе, а вторым проходом генерировали один-единственный раз только эти требуемые инстанциации. Так работал родной компилятор С++ для Sun Solaris.

Но в конечном итоге такой подход не выжил.

 Профиль  
                  
 
 Re: Ошибка Unresolved external. c++ builder 10.4
Сообщение11.02.2023, 11:20 
Заслуженный участник


02/08/11
7013
XeuTeP_KoLLIu в сообщении #1581053 писал(а):
я все равно не понимаю почему все работает именно так
Если речь про исходную проблему — всё работает именно так, потому что каждый .cpp файл компилируется независимо и не "видит" кода в других .cpp файлах.

(картинка)

Изображение

 Профиль  
                  
 
 Re: Ошибка Unresolved external. c++ builder 10.4
Сообщение11.02.2023, 23:52 


24/01/22
61
TheRuinedMap в сообщении #1581058 писал(а):
XeuTeP_KoLLIu в сообщении #1581053 писал(а):
Только я все равно не понимаю почему все работает именно так.


О чем именно речь? О шаблонах в целом? Или о тонкостях определения дружественных функций для шаблонных классов?

-- 10.02.2023, 10:00 --

worm2 в сообщении #1581055 писал(а):
Но, помнится, краем уха где-то слышал байку, что есть компиляторы, умеющие специализировать шаблон в рантайме.


Это что-то невероятное.

Были компиляторы, которые реализовывали другой подход к инстанцированию шаблонов во время компиляции. Вместо того, чтобы плодить множественные копии одного и того же кода, а потом вычищать лишние копии на стадии линковки (как поступают все современные реализации), они использовали двухпроходный подход: первым проходом они собирали информацию о том, какие специализации шаблонов используются в программе, а вторым проходом генерировали один-единственный раз только эти требуемые инстанциации. Так работал родной компилятор С++ для Sun Solaris.

Но в конечном итоге такой подход не выжил.

Дружественные функции.

 Профиль  
                  
Показать сообщения за:  Поле сортировки  
Начать новую тему Ответить на тему  [ Сообщений: 17 ]  На страницу 1, 2  След.

Модераторы: Karan, Toucan, PAV, maxal, Супермодераторы



Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей


Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете добавлять вложения

Найти:
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group