friend operator overloading in template class

#ifndef VEC_H
#define VEC_H

#include<iostream>
using std::cout;
using std::endl;
using std::ostream;
template<typename S>
class Vec{
private:
int len;
S *theVec;
public:
template<typename T>
Vec(T* x, int l);
template<typename T>
Vec(Vec<T> x);
int getLen(){ return len;}//accessor function needed
//since len is private
S *getVec(){//return a COPY of the array in Vec object
if ((theVec==NULL)or(len==0))
return NULL;
else{
S* v=new S[len];
for(int i=0; i< len; ++i)
v[i]=theVec[i];
return v;
}
}
//inline non-member friend operators
friend Vec operator+(const Vec &x, const Vec &y){
Vec z=Vec(x);
for (int i=0;i<=y.len;++i)
z.theVec[i]=x.theVec[i] + y.theVec[i];
return z;
}

friend Vec operator*(const S &alpha, const Vec & xx){
Vec zz=Vec(xx);
for(int i=0; i<xx.len; ++i)
zz.theVec[i]=alpha*zz.theVec[i];
return zz;
}
friend ostream &operator <<(ostream &out, const Vec &x){
for (int i=0; i< x.len;++i)
out<<x.theVec[i]<<endl;
return out;
}
};

why there is no such<T>or <S>in the friend operator overloading? Just Vec? Thanks!
It is already in the scope of the class, so the template parameter is already known.
So, if it is not defined in the class scope, then we should specify the parameter, right? Thanks for your kind reply!
Yes - because then the template parameter from the class is not in scope. ;)
On a seperate issue - I'm not convinced about these two constructors
1
2
3
4
5
	template<typename T>
	Vec(T* x, int l);
	
	template<typename T>
	Vec(Vec<T> x);


I have no idea what they do because you have not provided the source to them.
Last edited on
Understand! Thanks again:)
Yeah, it works, I have tried it. I think because it is in the class scope. Is this what you mean?
I mean the constructors do not have any visible definition - how are we to know what they do?
oh, this is just the first part of the whole code, and the definition is in the latter part. Because it does not relate to my question, I cut it off to save space. Thanks:)
Well, you see, that's the problem; you can't do it that way - template definitions must always be inline.
You mean the constructor should be inline? I remember my professor said the constructor should not be inline....
With templates, EVERYTHING should be inline.
Thanks for your kind reply:) I am a newbie, so, to make things clear: when you say template definition must always be inline, do you mean that I must provide the definition when the constructor appears at the first time? This is the whole code:
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
#ifndef VEC_H
#define VEC_H

#include<iostream>
using std::cout;
using std::endl;
using std::ostream;
template<typename S>
class Vec{
	private:
		int len;
		S *theVec;
	public:
		template<typename T>
		Vec(T* x, int l);// Allows us to define, e.g. complex Vec 
		                 //out of, say a float array
		template<typename T>
		Vec(Vec<T> x); //template copy constructor: Same as above

		int getLen(){ return len;}//accessor function needed
	                                  //since len is private

		S *getVec(){//return a COPY of the array in Vec object
			 if ((theVec==NULL)or(len==0))
				 return NULL;
			 else{
				 S* v=new S[len];
				 for(int i=0; i< len; ++i)
					 v[i]=theVec[i];
				 return v;
			 }
		}
		//inline non-member friend operators
		friend Vec operator+(const Vec &x, const Vec &y){
			Vec z=Vec(x);
			for (int i=0;i<=y.len;++i)
				z.theVec[i]=x.theVec[i] + y.theVec[i];
			return z;
		}

		friend Vec operator*(const S &alpha, const Vec & xx){
			Vec zz=Vec(xx);
			for(int i=0; i<xx.len; ++i)
				zz.theVec[i]=alpha*zz.theVec[i];
			return zz;
		}

		//This overloading of << for Vec<S> assumes that << is
		//also defined for S types. So, e.g. when you define 
		// Vec<complex> z;
		// then it is assumed for complex types << is already
		// defined.
		friend ostream &operator <<(ostream &out, const Vec &x){
			for (int i=0; i< x.len;++i)
				out<<x.theVec[i]<<endl;
			return out;
		}
};

template<typename S>
template<typename T>
Vec<S>::Vec(Vec<T> xx):
	len(xx.getLen()),
	theVec(new S[xx.getLen()]){

	//The following for loop assumes conversion from T to S 
	//is available. So for instance, if T is float and S is complex, 
	//then there should be 1-argument constructor turning float 
	//to complex. Also note that
	//   if T and S are different types,then Vec<T> and Vec<S> are different classes,
	// so "len" and
	//"theVec" members of Vec<T> are invisible to Vec<S>. That is
	//why we cannot write: theVec[i]= xx.theVec[i].

	T* xv=xx.getVec();
	for(int i=0; i<len;++i){
		theVec[i]=xv[i];
	}
}

template<typename S>
template<typename T>
Vec<S>::Vec(T* x, int l):
	len(l){
		theVec=new S[l];
		for(int i=0; i<l; ++i)
			theVec[i]=x[i];//assumes conversion from T to S
}
#endif 


It provides the definition outside the class scope, but still works. So do I think it in the wrong way? Thanks:)
It still works because both the declaration (in the class) and the definition (outside the class) are visible at the same time. If you were to include that in multiple source files the linker would complain that you defined it more than once, so you would then try to define the functions in their own source file. This is where the trouble comes: you can't without knowing all the template instantiations your entire code will use. You see, the compiler instantiates templates on the fly, so it needs the source code to work with - if it doesn't have that, you're going to have issues with the linker yes again.

So,long story short, if you ever use templates, always define them inline. This includes all member functions inside of a templated class, and it excludes prototypes for templated functions.
OK, so whenever I use the templates, I should always provide the definition at the first time to avoid any potential mistake. Thanks for your timely reply, I really appreciate it:)
Topic archived. No new replies allowed.