What does this error mean in the file: Makefile.win

Write your question here.
I am trying to compile my program and this is what I am getting:
It is complaining about the outstream (operator<<) and its address.

C:\Dev-Cpp\GenericListClassTemplate\main.o main.cpp:(.text+0xae): undefined reference to `listsavitch::operator<<(std::ostream&, listsavitch::GenericList<int> const&)'
C:\Dev-Cpp\GenericListClassTemplate\main.o main.cpp:(.text+0x128): undefined reference to `listsavitch::operator<<(std::ostream&, listsavitch::GenericList<char> const&)'
c:\program files\dev-cpp\mingw64\x86_64-w64-mingw32\bin\ld.exe main.o: bad reloc address 0x34 in section `.text$_ZN11listsavitch11GenericListIiEC1Ei[__ZN11listsavitch11GenericListIiEC1Ei]'
C:\Dev-Cpp\GenericListClassTemplate\collect2.exe [Error] ld returned 1 exit status
25 C:\Dev-Cpp\GenericListClassTemplate\Makefile.win recipe for target 'GenericList.exe' failed

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
  Put the code you need help with here.
//This is header file genericlist.h. This is the interface for the class GenericList.
//Objects of type GenericList can be a list of items of any type for which << and == are defined.
//All the items on any one list must be of the same type. A list that
//can hold up to max items all of type Type_name i declared as follows:
//    GenericList<Type_name> the_object(max):
#ifndef GENERICLIST_H
#define GENERICLIST_H
#include <iostream>
using namespace std;

namespace listsavitch
{
	template<class ItemType>
	class GenericList
	{
	public:
		GenericList(int max);
		//Initializes the object to an empty list that can hold up to
		//max items of type ItemType.
		~GenericList( );
		//REturns all the dynamic memory used by the object tp the freestore.
		
		int length( ) const;
		//REturns the number of items on the list.
		
		void add(ItemType new_item);
		//Precondition: The list is not full.
		//PostconditionL The new_item has been added to the list.
		
		bool full( ) const;
		//REturns true if the list is full.
		
		void erase( );
		//REmoves all items from the list so that the list is empty.
		
		friend ostream& operator <<(ostream& outs,
									const GenericList<ItemType>& the_list);
		//Overloads the << operator so it can be used to output the
		//contents of the list. The items are output one per line.
		//Precondition: If outs is a file output stream, then outs has
		//already been connected to a file.
	private:
		ItemType *item;  //pointer to the dynamic array that holds the list.
		int max_length;  //max number of items allowed on the list.
		int current_length;   // number of items currently on the list.
	}; 
}  //listsavitch
#endif   //GENERICLIST_H

//This is the implementation file: genericlist.cpp
//This is the implementation of class template named GenericList.
//The interface for the class template GenericList is in the header file genericlist.h
#ifndef GENERICLIST_CPP
#define GENERICLIST_CPP
#include<iostream>
#include<cstdlib>
#include "GenericList.h" //This is not needed when used as we are using this file,
						//but the #ifndef in genericlist.h makes it safe.
using namespace std;

namespace listsavitch
{
	template<class ItemType>
	GenericList<ItemType>::GenericList(int max) : max_length(max), current_length(0)
	{
		item = new ItemType[max];
	}
	
	template<class ItemType>
	GenericList<ItemType>::~GenericList( )
	{
		delete [] item;
	}
	
	template<class ItemType>
	int GenericList<ItemType>::length( ) const
	{
		return (current_length);
	}
	
	template<class ItemType>
	void GenericList<ItemType>::add(ItemType new_item)
	{
		if ( full() )
		{
			cout << "Error: adding to a full list.\n";
			exit(1);
		}
		else
		{
			item[current_length] = new_item;
			current_length = current_length + 1;
		}
	}
	
	template<class ItemType>
	bool GenericList<ItemType>::full( ) const
	{
		return (current_length == max_length);
	}
	
	template<class ItemType>
	void GenericList<ItemType>::erase( )
	{ 
		current_length = 0;
	}
	
	template<class ItemType>
	ostream& operator <<(ostream& outs, const GenericList<ItemType>& the_list)
	{
		for (int i = 0; i < the_list.current_length; i++)
			outs << the_list.item[i] << endl;
			
		return outs;
	}
}  //listsavitch
#endif   //GENERICLIST_CPP Notice that we have enclosed all the template
	     // definitions in #ifndef...#endif.		

//Program to demonstrate use of the class template GenericList.
#include <iostream>
#include "genericlist.h"
#include "genericlist.cpp"
using namespace std;
using namespace listsavitch;

int main() {
	
	GenericList<int> first_list(2);
	first_list.add(1);
	first_list.add(2);
	cout << "first_list = \n"
	     << first_list;
	GenericList<char> second_list(10);
	second_list.add('A');
	second_list.add('B');
	second_list.add('C');
	cout << "second_list = \n"
	     << second_list;
	     
	return 0;
}

try replacing
cout << "second_list = \n"
<< second_list;
with
cout << "second_list = \n";
cout << second_list;
and for first list as well. Also, if you could send a zip over on media fire. Thank you.
Are those the only "errors" reported?

Why are you #including a .cpp file in another .cpp file?

You are working with templates, so the definition and implementation must be in the same compilation unit, which usually means everything resides in the header file.

If you want to "#include" the implementation #included in the header file after the class definition, and normally you would use some other file extension for the implementation, perhaps ".inc".

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
#ifndef GENERICLIST_H
#define GENERICLIST_H
#include <iostream>
using namespace std;

namespace listsavitch
{
	template<class ItemType>
	class GenericList
	{
	public:
		GenericList(int max);
		//Initializes the object to an empty list that can hold up to
		//max items of type ItemType.
		~GenericList( );
		//REturns all the dynamic memory used by the object tp the freestore.
		
		int length( ) const;
		//REturns the number of items on the list.
		
		void add(ItemType new_item);
		//Precondition: The list is not full.
		//PostconditionL The new_item has been added to the list.
		
		bool full( ) const;
		//REturns true if the list is full.
		
		void erase( );
		//REmoves all items from the list so that the list is empty.
		
		friend ostream& operator <<(ostream& outs,
									const GenericList<ItemType>& the_list);
		//Overloads the << operator so it can be used to output the
		//contents of the list. The items are output one per line.
		//Precondition: If outs is a file output stream, then outs has
		//already been connected to a file.
	private:
		ItemType *item;  //pointer to the dynamic array that holds the list.
		int max_length;  //max number of items allowed on the list.
		int current_length;   // number of items currently on the list.
	}; 


// #include the implemenation here.

#include "yourImplementationFile"

}  //listsavitch

#endif   //GENERICLIST_H 


Also be careful C++ is case sensitive, #include "GenericList.h" is not the same as #include "genericlist.h".

By the way your friend definition doesn't look correct, it seem to be missing the template<> designation.

Topic archived. No new replies allowed.