Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > C/C++ программирование > Общие вопросы C/C++
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 13.03.2011, 01:54   #1
РагнаР
Пользователь
 
Регистрация: 19.10.2010
Сообщений: 25
По умолчанию Шаблоны класса и специализация

Нужно реализовать класс двусторонняя очередь- дек на шаблонах работающий для целых типов и для строк типа char*(без стл).
Возникает проблема при специализации метода.
Вот собственно и сам класс:
Код:
#include<iostream>
template<class TInfo>
class TDeque
{
protected:
	struct TDequeItem
	{
		TInfo Info;
		TDequeItem* Next;
		TDequeItem* Prev;
	};
	TDequeItem *Front,*Rear;
	int Size;
	void Erase();
	void Clone(const TDeque &);
	void DeleteItem(TDequeItem*);
	void* PtrByIndex(int)const;
public:

	class error{};
	TDeque()
	{
		Front=NULL;Rear=NULL;Size=0;
	}
	TDeque (const TDeque &);
	virtual ~TDeque();
	void InsFront(TInfo);
	void InsRear(TInfo);
	bool DelFront(TInfo &);
	bool DelRear(TInfo &);
	const TDeque& operator = (const TDeque &);
	const TInfo& GetByIndex(unsigned)const;
	void SetByIndex(TInfo,unsigned);
	void Browse(void(TInfo&));
	void Browse(void(TInfo))const;
	void Print()const;
};
template<typename TInfo>void TDeque<TInfo>::DeleteItem(TDequeItem *A)
{
	delete A;
	Size--;
}
template<>void TDeque<char*>::DeleteItem(TDequeItem *A)
{
	delete []A->Info;
	delete A;
	Size--;
}
template<typename TInfo>bool TDeque<TInfo>::DelFront(TInfo &q)
{
	if(Front==NULL)
		return false;
	else
	{
		q=Front->Info;
		TDequeItem*p=Front;
		Front=Front->Next;
//		Front->Prev=NULL;
		DeleteItem(p);
		return true;
	}
}
template<>bool TDeque<char*>::DelFront(char* &a)//Вот проблема в этом месте
{
	if(Front==NULL)
		return false;
	else
	{
		delete[]a;
		a=new char[strlen(Front->Info)+1];
		strcpy(a,Front->Info);
		TDequeItem*p=Front;		
		Front=Front->Next;
//		Front->Prev=NULL;
		DeleteItem(p);
		return true;
	}
}
Текст ошибки:
1>c:\users\admin\documents\visual studio 2008\projects\labrab\deque(template )\deque_header.h(188) : error C2908: explicit specialization; 'bool TDeque<TInfo>::DelFront(TInfo &)' has already been instantiated

В чем проблема и как её исправить?
РагнаР вне форума Ответить с цитированием
Старый 13.03.2011, 02:28   #2
pproger
C++ hater
СтарожилДжуниор
 
Аватар для pproger
 
Регистрация: 19.07.2009
Сообщений: 3,333
По умолчанию

у меня нормально вызывается и обычный, и специализированный метод. покажи, как используешь
I invented the term Object-Oriented, and I can tell you I did not have C++ in mind. (c)Alan Kay

My other car is cdr.

Q: Whats the object-oriented way to become wealthy?
A: Inheritance

Последний раз редактировалось pproger; 13.03.2011 в 02:39.
pproger вне форума Ответить с цитированием
Старый 13.03.2011, 02:37   #3
onewho
Форумчанин
 
Регистрация: 29.09.2010
Сообщений: 636
По умолчанию

у меня и так компилируется..
может попробуйте template<> удалить ?
onewho вне форума Ответить с цитированием
Старый 13.03.2011, 02:37   #4
РагнаР
Пользователь
 
Регистрация: 19.10.2010
Сообщений: 25
По умолчанию

Цитата:
Сообщение от pproger Посмотреть сообщение
у тебя шаблонный класс, а ты хочешь частично специализировать один метод? так нельзя
А поподробнее можно? Почему тогда не возникает проблем с такой функцией?
Код:
template<typename TInfo>void TDeque<TInfo>::SetByIndex(TInfo info, unsigned int k)
{
	((TDequeItem*)PtrByIndex(k))->Info=info;
}
template<>void TDeque<char*>::SetByIndex(char* info, unsigned int k)
{
	char *tmp=(char*)((TDequeItem*)PtrByIndex(k))->Info;
	delete []tmp;
	tmp=new char[strlen(info)+1];
	strcpy(tmp,info);
	((TDequeItem*)PtrByIndex(k))->Info=tmp;
РагнаР вне форума Ответить с цитированием
Старый 13.03.2011, 02:42   #5
РагнаР
Пользователь
 
Регистрация: 19.10.2010
Сообщений: 25
По умолчанию

Цитата:
Сообщение от pproger Посмотреть сообщение
у меня нормально вызывается и обычный, и специализированный метод. покажи, как используешь
Код:
TDeque<char*>q;
	char*a=new char;
	q.InsFront("mk");
	q.DelFront(a);
РагнаР вне форума Ответить с цитированием
Старый 13.03.2011, 02:45   #6
pproger
C++ hater
СтарожилДжуниор
 
Аватар для pproger
 
Регистрация: 19.07.2009
Сообщений: 3,333
По умолчанию

2РагнаР
у тебя InsFront не специализирован на char *, поэтому твой приведенный код не скомпилится

Код:
TDeque<char*>q;
char*a=new char;
q.DelFront(a);
вот так у меня все компилится

может ты этот файл инклудишь в нескольких местах? стражи включения (ifndef-define-endif) стоят на хидер?

Цитата:
А поподробнее можно? Почему тогда не возникает проблем с такой функцией?
я бред сказанул, конечно методы можно специализировать
I invented the term Object-Oriented, and I can tell you I did not have C++ in mind. (c)Alan Kay

My other car is cdr.

Q: Whats the object-oriented way to become wealthy?
A: Inheritance

Последний раз редактировалось pproger; 13.03.2011 в 02:49.
pproger вне форума Ответить с цитированием
Старый 13.03.2011, 02:48   #7
РагнаР
Пользователь
 
Регистрация: 19.10.2010
Сообщений: 25
По умолчанию

Цитата:
Сообщение от pproger Посмотреть сообщение
2РагнаР
у тебя InsFront не специализирован на char *, поэтому твой приведенный код не скомпилится

[qoute]
А поподробнее можно? Почему тогда не возникает проблем с такой функцией?
я бред сказанул, конечно методы можно специализировать[/QUOTE]


Я просто не всю программу сбросил, вот InsFront


Код:
template<typename TInfo> void TDeque<TInfo>::InsFront(TInfo A) 
{
	TDequeItem *p=new TDequeItem;
	p->Info=A;
	p->Next=Front;
	Front=p;
	if(Rear==NULL)
		Rear=p;
	else
	{
		(p->Next)->Prev=p;
	}
	p->Prev=NULL;
		Size++;
}
template<>void TDeque<char*>::InsFront(char* A)
{
	TDequeItem *p=new TDequeItem;
	p->Info=new char[strlen(A)+1];
	strcpy(p->Info,A);
	p->Next=Front;
	Front=p;
	if(Size==0)
		Rear=p;
	else
	{
		(p->Next)->Prev=p;
	}
	Size++;
}
РагнаР вне форума Ответить с цитированием
Старый 13.03.2011, 02:52   #8
pproger
C++ hater
СтарожилДжуниор
 
Аватар для pproger
 
Регистрация: 19.07.2009
Сообщений: 3,333
По умолчанию

2РагнаР
Цитата:
может ты этот файл инклудишь в нескольких местах? стражи включения (ifndef-define-endif) стоят на хидер?
вобщем попробовал в 2003 студии, все норм. специализация правильная. где то ты второй раз специализируешь
I invented the term Object-Oriented, and I can tell you I did not have C++ in mind. (c)Alan Kay

My other car is cdr.

Q: Whats the object-oriented way to become wealthy?
A: Inheritance

Последний раз редактировалось pproger; 13.03.2011 в 03:01.
pproger вне форума Ответить с цитированием
Старый 13.03.2011, 10:05   #9
РагнаР
Пользователь
 
Регистрация: 19.10.2010
Сообщений: 25
По умолчанию

Цитата:
Сообщение от pproger Посмотреть сообщение
2РагнаР


вобщем попробовал в 2003 студии, все норм. специализация правильная. где то ты второй раз специализируешь
Студия 2008года. Файла в программе только два:header и main.
Полный текст header вот
http://ideone.com/mxTLp
РагнаР вне форума Ответить с цитированием
Старый 13.03.2011, 19:29   #10
pproger
C++ hater
СтарожилДжуниор
 
Аватар для pproger
 
Регистрация: 19.07.2009
Сообщений: 3,333
По умолчанию

я не очень хорошо разбираюсь в шаблонах, но вот:
Код:
template<>void TDeque<char*>::Erase()
{
        char*A=new char;
        while(DelFront(A));
        Size=0;
}
Erase у тебя так же специализирован на char *, в котором ты вызываешь DelFront. Erase пока не знает, что ты специализировал DelFront на char * (ибо он описан ниже), поэтому инстанцируется метод DelFront<char *> из DelFront<T>. а потом ты опять определяешь DelFront<char *>, хотя у тебя он уже есть.

просто объяви Erase<char *> ПОСЛЕ DelFront<char *>
I invented the term Object-Oriented, and I can tell you I did not have C++ in mind. (c)Alan Kay

My other car is cdr.

Q: Whats the object-oriented way to become wealthy?
A: Inheritance
pproger вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Шаблоны - нужно создать объект класса abc в котором вместо aa использовался бы объект класса fff? Farrel Общие вопросы C/C++ 2 13.11.2010 17:37
Параметр конструктора класса = объект этого класса nazavrik Общие вопросы C/C++ 6 14.02.2010 13:48
Если в классе объявить объект другого класса,будет ли видно переменные первого класса из объекта второго? TwiX Общие вопросы Delphi 3 15.11.2009 00:54
C++ Специализация шаблона opensuse2008 Помощь студентам 7 07.06.2009 18:00