How to handle template arrays being passed to functions

I have a template of an array class. I want to overload the << operator to print out the array, so i need to pass in the array, but I cannot figure out how to do this with a template. I have the overloaded function as a friend function (at the very bottom of the code piece), and I am using T as the type, but the compiler complains that the identifier is undefined. I can fix this by using int, float etc, but i want this function to work with all types, so how would I do that?

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

  #pragma once
#include <assert.h>  
template <typename T>
class Array
{
private:
	T* ptr{nullptr};
	int size{ 0 };

public:
	friend std::ostream& operator<< (std::ostream& stream, const Array<T>& obj);
	bool isEmpty() const
	{
		return (size == 0);
	}

	int sizeArray() const
	{
		return size;
	}

	bool IsValidIndex(int index) const {
		return (index >= 0) && (index < size);
	}

	int& operator[] (int index) const
	{
		if (IsValidIndex(index))
		{
			return ptr[index];
		}		
	}

	//constructor
	explicit Array(int Size) 
	{
		assert(Size >= 0);
		if (Size != 0)
		{
			size = Size;
			ptr = new T[size]{};
			
		}
	}

	//copy constructor
	Array(const Array& obj)
	{
		std::cout << "Copy construct\n\n";
		if (!obj.isEmpty())
		{
			size = obj.size;
			ptr = new T[size];

			for (int i = 0; i < size; i++)
			{
				ptr[i] = obj.ptr[i];
			}
		}
	}

	//copy assign
	Array& operator= (const Array& obj)
	{
		std::cout << "copy assignment\n\n";
		if (this != *obj)
		{
			size = obj.size;
			ptr = obj.ptr;
			obj.size = 0;
			obj.ptr = nullptr;
		}
		return this;
	}

	//move constructor
	Array(Array&& obj)
	{
		std::cout << "Move constructor\n\n";
		size = obj.size;
		ptr = obj.ptr;

		obj.size = 0;
		obj.ptr = nullptr;
	}

	//move assign
	Array operator=(Array&& obj)
	{
		std::cout << "Move assignment\n\n";
		if (this != *obj)
		{
			size = obj.size;
			ptr = obj.ptr;

			obj.size = 0;
			obj.ptr = nullptr;
		}
	}
	//destructor
	~Array()
	{
		std::cout << "Destructor\n\n";
		delete[] ptr;
	}
};

std::ostream& operator<< (std::ostream& stream, const Array<T>& obj)
{
	stream << "[";
	for (int i = 0; i < obj.sizeArray(); i++)
	{
		stream << obj[i] << ",";
	}
	stream << "]\n";

	return stream;
}
If you use a symbol like 'T', you need to put template <typename T> before the class/function so that the compiler knows it's for a template (line 108).
Last edited on
thank you, have it working now

EDIT: Everything works if I do not have the overloaded function as a friend function, but if it is a friend function, i get a linker error. I struggle with reading linking errors. so if possible could someone help me out why i could be getting this issue with the friend function.

The error says: unresolved external symbol "class std::basic_ostream<char,struct std::char_traits<char> > & __cdecl operator<<(class std::basic_ostream<char,struct std::char_traits<char> > &,class Array<int> const &)" (??6@YAAAV?$basic_ostream@DU?$char_traits@D@std@@@std@@AAV01@ABV?$Array@H@@@Z) referenced in function _main arrayTemplates
Last edited on
See 'Why do I get linker errors when I use template friends?'
https://isocpp.org/wiki/faq/templates#template-friends
Topic archived. No new replies allowed.