Creating <Template>. unknow compile error.

This is study project because of this I don't use code from STL vector.
I want to create some program that will be do next:
1. Create object of class for example Point (class that has x,y coordinate)
2. Create object of <template> name "Array" with fix amount of elements.
3. Put object of class Point to Array on needed me place that represent index of Array. Using fucntion SetElement
4. Using function GetElement I want to this this "Point" object on screen.
Very simple, please help !!! What I did wrong ???
5. I create object of "Point " dynamically because of condition of study project.

Please I really just want to see correction of code even without comments...
Thanks in advance


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
// Array.h
// Templated Array class containging Ts
#include <sstream>
#include <iostream>

#ifndef Array_H
#define Array_H
 
template <class Type=double> class Array
{
private:
int m_size; 
Type* m_data;
 
public:
Array();
Array(int new_size); 
void SetElement(Type& type_object, int index); 
const Type& GetElement(int index) const; 
};
 

#ifndef Array_cpp 
#include "array.cpp"
#endif
 
#endif

//*********************

//array.cpp
#include "array.h"
#include <sstream>
#include <iostream>
using namespace std;
#ifndef Array_CPP
#define Array_CPP

template <class Type>
Array<Type>::Array()                                     
{
    m_size = 10;
     m_data = new Type[m_size];
}

template <class Type> 
Array<Type>::Array(int new_size)					
{
    new_size = m_size;
    m_data = new Type[m_size];
}


template <class Type> 
void Array<Type>::SetElement(Type& type_object, int index)
{
	try
	{
		if (index >= m_size){throw 11;} 
		m_data[index] = type_object;
		cout << "Set Element " << type_object  << endl;
	}
	 catch (int x )
	 {
		cout << "ERROR" << x << " ignore the set, because index of element bigger then massive size"<< endl;
	 }
}
template <class Type> 
const Type& Array<Type>::GetElement(int index) const
{
	try 
	{
		if (index > m_size || index < 0){ throw 1;} 
	} 
	catch (double x)
	{
	cout << "index incorrect, index too big or too small " << x << endl; 
	}  
	return m_data[index];
}
#endif Array_CPP

//********************

		//main.cpp
		#include <iostream>
		#include <sstream>
		#include "array.h"
		using namespace std;

	class Point
{
private:
    double m_x;                                
    double m_y;                                
public:
    // Constructors
    Point(): m_x(0), m_y(0) {};                            
	Point(double new_x, double new_y) : m_x(new_x), m_y(new_y) {};
};


		int main()
		{
			Point *p1 = new Point (1,12);
				cout << endl; 
			Array<Point> arr1[1];
			arr1[1].SetElement(*p1,0);
				cout << endl;
			arr1[1].GetElement(0) ;	
			delete p1;
			return 0;
		}
 


Compiler errors give a lot of words related with streams or something for examlple :
_Traits=std::char_traits<char>
1> ]
1> c:\Program Files\Microsoft Visual Studio 10.0\VC\include\ostream(467): or 'std::basic_ostream<_Elem,_Traits> &std::basic_ostream<_Elem,_Traits>::operator <<(const void *)'
1> with

1>------ Build started: Project: HP_4.2a, Configuration: Release Win32 ------
1> TestArray.cpp
1>c:\all my\с++\ha level 6\solution\level 6\hp_4.2a\array.cpp(31): error C2679:
1> TestArray.cpp(23) : see reference to class template instantiation
Last edited on


Now I done some correction and my whole compiler error is:
1>------ Build started: Project: 42a, Configuration: Debug Win32 ------
1> Skipping... (no relevant changes detected)
1> Array.cpp
1>main.obj : error LNK2019: unresolved external symbol "public: __thiscall Array<class Point>::~Array<class Point>(void)" (??1?$Array@VPoint@@@@QAE@XZ) referenced in function _main
1>C:\all my\с++\HA level 6\Solution1\Level6\Debug\42a.exe : fatal error LNK1120: 1 unresolved externals
========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ==========

but compiler open to me console window where I can see the next message... This message on my native language I try to translate... main idea is that it refers me to folder from place my .exe file that tell that this .exe " are not an internal or external command, used by the program or batch file."
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
// Array.h
// Templated Array class containging Ts
#include <sstream>
#include <iostream>

#ifndef Array_H
#define Array_H
 
template <class Type> class Array
{
private:
Type* m_data;
int m_size; 
 
public:
Array();
Array(int new_size); 
void SetElement(Type& type_object, int index); 
const Type& GetElement(int index) const; 
~Array();
};
 

#ifndef Array_cpp 
#include "array.cpp"
#endif
 
#endif

//array.cpp
#include "array.h"
#include <sstream>
#include <iostream>
using namespace std;
#ifndef Array_CPP
#define Array_CPP

template <class Type>
Array<Type>::Array()                                     
{
    m_size = 10;
     m_data = new Type[m_size];
}

template <class Type> 
Array<Type>::Array(int new_size)					
{
    new_size = m_size;
    m_data = new Type[m_size];
}


template <class Type> 
void Array<Type>::SetElement(Type& type_object, int index)
{
	try
	{
		if (index >= m_size){throw 11;} 
		m_data[index] = type_object;
		cout << "Set Element " << type_object  << endl;
	}
	 catch (int x )
	 {
		cout << "ERROR" << x << " ignore the set, because index of element bigger then massive size"<< endl;
	 }
}
template <class Type> 
const Type& Array<Type>::GetElement(int index) const
{
	try 
	{
		if (index > m_size || index < 0){ throw 1;} 
	} 
	catch (double x)
	{
	cout << "index incorrect, index too big or too small " << x << endl; 
	}  
	return m_data[index];
}
#endif //Array_CPP

		//main.cpp
		#include <iostream>
		#include <sstream>
		#include "array.h"
		using namespace std;

	class Point
{
private:
    double m_x;                                
    double m_y;                                
public:
    // Constructors
    Point(): m_x(0), m_y(0) {};                            
	Point(double new_x, double new_y) : m_x(new_x), m_y(new_y) {};
	friend ostream& operator << (ostream& os, const Point& point)
{
    return os << point.ToString();
}
	std::string Point::ToString(void) const                // create a string representation of a point
{
// create a string like: “Point(1.5, 3.9)”
      std::ostringstream os;
    os << m_x << " , " << m_y;
    std::string double_string = os.str();
 
    return "Point(" + double_string + ")";
}
};


		int main()
		{
			Point *p1 = new Point (1,12);
				cout << endl; 
			Array<Point> arr1[1];
			arr1[1].SetElement(*p1,0);
				cout << endl;
			arr1[1].GetElement(0) ;	
			delete p1;
			return 0;
		}
 
Any template function definition needs to be in the same file as the declaration.

You shouldn't need to include .cpps, or have #ifnd/#define per-processor directives in them.

I would also avoid using the word Array to make a custom class, but that is probably just me. Another thing to think about is splitting those classes/main functions into different files. One purpose of these classes is that once your Array is working properly you should be able to copy/paste it into any project you might be working on.
closed account (zb0S216C)
Template definitions must reside within the file in which they are declared. This is because the linker will not be able to detect the definitions within a source file; thus, a linker error. This is because templates are not complete types. As a result, when the source file is compiled, the compiler hasn't got all the information it needs to compile the source file. This is where "Explicit Specialisation" comes in.

Explicit specialisation basically means: "Generate a template of class X with type Y." This forms a complete type; thus, can be compiled in source files. For example:

Header File:

1
2
3
4
5
6
7
8
9
10
#ifndef HEADER_IMPL
#define HEADER_IMPL

template <typename T>
struct Something
{
    Something();
};

#endif 

Source File:

1
2
3
4
5
#include "Header File"

// Explicit specialisation:
template<>
Something<int>::Something() { }

Edit: I got the name for the term wrong. My bad.

Wazzak
Last edited on
Many thanks !!!!
Topic archived. No new replies allowed.