LINUX.ORG.RU

C++ , Шаблоны, ошибка линкера LNK2019


0

0

У меня имеется класс:
template <class T>
class List {
	int N;							//Number of elements
	Elem<T> *Head;					//Head of list
public:
//Constructors
	List(void);
	List(T&);

//Methods
	void AddElem (T&, int);			//Additional Elem to List by logical number
	void DelElem (int);				//Delete Elem by logical number
	int Max (int);					//Search maximum of elements
	int Min (int);					//Search minimum of elements
	void Sort (void);				//Sorting insets
	Elem<T> *Get (int);				//Get point to Elem by set number
	
//Operations for work with streams
	friend std::istream &operator>><>(std::istream &,List<T> &);
	int Save (char *);				//Save list into the set file
	
};

Компиляция проходит успешно, а вот при линковке выдается сообщение:
error LNK2019: unresolved external symbol "class std::basic_istream<char,struct std::char_traits<char> > & __cdecl >>(class std::basic_istream<char,struct std::char_traits<char> > &,class List<class NumString> &)" (?>>@@YAAAV?$basic_istream@DU?$char_traits@D@std@@@std@@AAV12@AAV?$List@VNumStr
ing@@@@@Z) referenced in function _main

Причем когда комменчу определение функции Save  и ее реализацию, то все линкуется на ура.

Вот реализация функции Save:

int List<NumString>::Save(char *s)
{/*
	FPTR pos;
	BinFile BF;
	if (!BF.Create(s)) return 0;
	if (!BF.Open(s)) return 0;
	pos=BF.tellg();
	Elem<NumString> *ptr=Head;	
	for (int i=0;i<N;i++)
	{
		ptr->Obj->Save(s,pos);
		pos=BF.tellg();
		ptr=ptr->Next;
	} */
	return 1;
}

А также реализация оператора >>, о коем упоминается в ошибке линковщика:

template <class T>
std::istream &operator>>(std::istream& IO, List<T> &Spisok)
{//IO - input stream, Spisok - List of objects
	T Obj;
	IO >> Obj;
	Spisok.AddElem(Obj,0);
	return IO;
}

Скажите, пожалуйста, что я сделал не так и возможно ли вообще такое опредение функции Save (я явно указал значение параметра шаблона). Заранее спасибо!

Ответ на: комментарий от Reset

И обявление класс и его реализация лежат в одном файле .h

PirateTigo
() автор топика

> int List<NumString>::Save(char *s)

а объявление для <class T>::Save у тебя есть?

NumString определен?

код тяжело читать, попробуй удалить все объектники - возможно у тебя собрался объектник с одним определением, потом ты пофиксил чего и в зависимостях *.h не прописанны, а другой с другим определением слинковался в итоге ошибка компилятора на линковке

fura13 ★★★
()
Ответ на: комментарий от fura13

>NumString определен? да определен

>а объявление для <class T>::Save у тебя есть?

Нет, собственно в этом и состоит вторая часть вопроса. Мне нужно реализовать функцию Save для типа NumString и для типа int. Вот я и подумал, что возможно это нужно сделать как:

int List<NumString>::Save(char *s) {...};

int List<int>::Save(char *s) {...};

Или так делать нельзя? А если нельзя, то как это можно сделать?

>код тяжело читать, попробуй удалить все объектники - возможно у тебя собрался объектник с одним определением, потом ты пофиксил чего и в зависимостях *.h не прописанны, а другой с другим определением слинковался в итоге ошибка компилятора на линковке

...не помогает

PirateTigo
() автор топика
Ответ на: комментарий от BreadFan

>попробуй вместо: &operator>>(std::istream& IO, написать &operator>>(const std::istream& IO,

Чтение из потока меняет его внутреннее состояние. ostream и istream передают по не-const ссылке.

Absurd ★★★
()
Ответ на: комментарий от PirateTigo

>Мне нужно реализовать функцию Save для типа NumString и для типа
>int. Вот я и подумал, что возможно это нужно сделать как: 

>int List<NumString>::Save(char *s) {...}; 

>int List<int>::Save(char *s) {...}; 

>Или так делать нельзя? А если нельзя, то как это можно сделать?

#include <iostream>
#include <string>

template<class T>
class A
{
    public:
        void sort();
};

template<class T>
void A<T>::sort()
{
    std::cout << "A<T>::sort()" << std::endl;
}

template<>
void A<int>::sort()
{
    std::cout << "A<int>::sort()" << std::endl;
}

template<>
void A<std::string>::sort()
{
    std::cout << "A<string>::sort()" << std::endl;
}

int main()
{
    A<int> a;
    A<std::string> b;
    A<double> c;

    a.sort();
    b.sort();
    c.sort();

    return 0;
}

alex_custov ★★★★★
()
Ответ на: комментарий от BreadFan

упс, ступил, не обращай внимания: была когда-то подобная проблема, вот и брякнул не вчитываясь особенно.

BreadFan ★★
()
Ответ на: комментарий от alex_custov

Занятно, но я только что попробовал перенести реализацию операции >> в класс и все слинковалось, то есть мой способ для определения Save тоже подойдет. Только вот почему нельзя сделать так, чтобы определение операции >> было за пределами объявления класса?..

PirateTigo
() автор топика
Ответ на: комментарий от Absurd

согласен, сказал не думая. у меня было что-то показавшееся мне похожим: был оператор <<, и ему алгоритомом copy отдавалось содержимое контейнера. просто вывод объекта в поток работал, а через copy - не _компилялось_. оказывается, компилятор ждал объявления const у _второго_ аргумента оператора.

BreadFan ★★
()
Ответ на: комментарий от PirateTigo

>Только вот почему нельзя сделать так, чтобы определение операции >> было за пределами объявления класса?..

за пределами класса надо inline писать

Vinick ★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.