Форум программистов «Весельчак У»
  *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

  • Рекомендуем проверить настройки временной зоны в вашем профиле (страница "Внешний вид форума", пункт "Часовой пояс:").
  • У нас больше нет рассылок. Если вам приходят письма от наших бывших рассылок mail.ru и subscribe.ru, то знайте, что это не мы рассылаем.
   Начало  
Наши сайты
Помощь Поиск Календарь Почта Войти Регистрация  
 
Страниц: [1]   Вниз
  Печать  
Автор Тема: template и unresolved external symbol  (Прочитано 8424 раз)
0 Пользователей и 3 Гостей смотрят эту тему.
yudjin
Помогающий

ua
Offline Offline
Пол: Мужской

« : 03-07-2011 11:42 » 

Начал осваивать шаблоны в с++, линковщик ругается следующим:
Цитата
error LNK2019: unresolved external symbol "public: __thiscall Array_Stack<char>::~Array_Stack<char>(void)" (??1?$Array_Stack@D@@QAE@XZ) referenced in function _wmain   
MS VS 2010.

Задним местом чую, что ошибка элементарная, но решить не могу. Гугль пишет
Цитата
Question: You have included the templates in every source file? (you should answer YES).
Question: You are not using function prototypes for template funcitons? (You should answer YES).
Как подключить шаблоны в сорц? Что значит "не используйте прототипы функций для шаблонных функций"... Здесь была моя ладья...

Array_Stack.h
Код:
#pragma once
template<class T> class Array_Stack //: public MyStack<T>
{
private:
T* arr;
int top;
int maxSize;

public:
Array_Stack(int size);
~Array_Stack(void);

T pop();
void push(T ch);
};



Array_Stack.cpp
Код:
#pragma once

#include "StdAfx.h"
#include "Array_Stack.h"

template<class T> Array_Stack<T>::Array_Stack(int size)
{
maxSize = size;
arr = new T[maxSize];
top = 0;
}

template<class T> T Array_Stack<T>::pop()
{
if(top == 0)
{
throw Overflow();
}

top--;
return arr[top];
}

template<class T> void Array_Stack<T>::push(T ch)
{
if(top == maxSize)
{
throw Overflow();
}

arr[top] = ch;
top++;
}

template<class T> Array_Stack<T>::~Array_Stack()
{
delete [] arr;
}

main
Код:
#pragma once

#include "stdafx.h"
#include <iostream>
#include "Array_Stack.h"

int _tmain(int argc, _TCHAR* argv[])
{
int size = 10;
Array_Stack<char> myStack (size);

int x;
std::cin >> x;
return 0;
}

Записан
RXL
Технический
Администратор

Offline Offline
Пол: Мужской

WWW
« Ответ #1 : 03-07-2011 13:05 » 

yudjin, полагаю, нужно инстанцировать шаблон для char, чтобы компилятор сгенерировал методы образующегося класса. И в параметрах деструктора void не нужен.
Записан

... мы преодолеваем эту трудность без синтеза распределенных прототипов. (с) Жуков М.С.
yudjin
Помогающий

ua
Offline Offline
Пол: Мужской

« Ответ #2 : 03-07-2011 13:23 » new

Да это пример из книжки Страуструпа. Перечитал в очередной раз - ни о каком инстанциировании не идет речи...

На всякий случай добавил явное инстанциирование
template class Array_Stack<char>;
Ничего не поменялось.

Записан
RXL
Технический
Администратор

Offline Offline
Пол: Мужской

WWW
« Ответ #3 : 03-07-2011 13:31 » 

Инстанцирование нужно проводить в Array_Stack.cpp, т.к. в main.cpp компилятор ничего не знает о коде твоих методов.
Либо перенести содержимое Array_Stack.cpp в заголовочный файл.
Надеюсь, ты уже понял, почему?
« Последнее редактирование: 03-07-2011 13:34 от RXL » Записан

... мы преодолеваем эту трудность без синтеза распределенных прототипов. (с) Жуков М.С.
yudjin
Помогающий

ua
Offline Offline
Пол: Мужской

« Ответ #4 : 03-07-2011 13:59 » 

Пока еще не совсем понял - наверное связано с тем, что шаблоны - механизм времени компиляции.
Перенос template class Array_Stack<char>; в Array_Stack.cpp помог, равно как и перенос кода из срр в заголовочный файл.

Отсюда можно сделать вывод - реализация моих шаблонных классов должна быть в заголовочном файле?

В любом случае - спасибо. Буду рыть дальше.
Записан
RXL
Технический
Администратор

Offline Offline
Пол: Мужской

WWW
« Ответ #5 : 03-07-2011 17:16 » 

Верно мыслишь. Шаблоны не генерят исполнимого кода — код дает инстанцирование, явное или неявное. В момент инстанцирования должен быть доступен текст используемых в программе свойств и методов.
« Последнее редактирование: 03-07-2011 17:26 от RXL » Записан

... мы преодолеваем эту трудность без синтеза распределенных прототипов. (с) Жуков М.С.
Вад
Команда клуба

ru
Offline Offline
Пол: Мужской

« Ответ #6 : 03-07-2011 20:05 » 

Строго говоря, в стандарте описан механизм экспорта шаблонов, и вообще-то, предполагалось, что со временем будет проработана технология, позволяющая писать шаблоны так же, как и все прочие классы, вплоть до возможностей создавать готовые библиотеки (в частности, создатель STL Александр Степанов упирал на нужность такой технологии). Но пока - увы, оно так, как оно есть.

То есть, теоретически, экспорт шаблонов должен работать, а на практике шаблоны описывают в заголовочных файлах. Поскольку как-то нет стимула пробовать пользоваться этой фичей, то не могу сказать, насколько сегодня компиляторы это дело поддерживают. Одно время назад кое-какая поддержка была, но с ней добавлялась какая-то головная боль, уже не вспомню в деталях.
« Последнее редактирование: 03-07-2011 20:08 от Вад » Записан
Страниц: [1]   Вверх
  Печать  
 

Powered by SMF 1.1.21 | SMF © 2015, Simple Machines