Explicit Template Instantiation

Please refer the article: http://www.cplusplus.com/forum/articles/14272/

I am using the method described in the article for explicit template instantiation in a separate .cpp file with my class declaration in a .h file. Here is the description of the class:


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
template <int N>
class vector {
public:
	double basis[N];
public:
	vector<N>(){for(int i=0;i<N;i++)basis[i]=0;}
	vector<N>(double values[N]) {for(int i=0;i<N;i++)basis[i]=values[i];}
	vector<N> operator= (vector<N>);
	vector<N> operator+ (vector<N>);
	double operator* (vector<N>);
	vector<N> operator* (double);
	vector<N> operator- (vector<N>);
//	vector operator^ (vector);		// Not needed right now
	double mag ();
	vector<N> operator+= (vector<N>);
	vector<N> operator-= (vector<N>);
	vector<N> operator*= (double);
	bool operator== (vector<N>);
	template <unsigned int M>
		friend vector<M> operator* (double, vector<M>);
	vector<N> operator/ (double);
};


The .cpp file contains all definitions of these functions. In particular I have the friend function also defined:

1
2
3
4
5
6
7
template <int N>
vector<N> operator* (double l, vector<N> a) {
	vector<N> r;
	for (int i=0;i<N;i++)
		r.basis[i]=a.basis[i]*l;
	return r;
}


In the end, I am explicitly instantiating:

1
2
3
template class vector<1>;
template class vector<2>;
template class vector<3>;


However, still, the compiler complains that there is no definition for the function 'operator*' that takes (double, vector<1>) or (double, vector<2>) or (double, vector<3>) as arguments. I need this feature to be present. Any help will be appreciated.
You need to move that function definition to the header file and make it inline.

Template functions are generated on the fly. If the definition of a methid isn't seen, the compiler doesn't generate code for it. Templates, at first glance, appear to be different in this regard.
I have tried it. Here is what I did:


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
template <int N>
class vector {
public:
	double basis[N];
public:
	vector<N>(){for(int i=0;i<N;i++)basis[i]=0;}
	vector<N>(double values[N]) {for(int i=0;i<N;i++)basis[i]=values[i];}
	vector<N> operator= (vector<N>);
	vector<N> operator+ (vector<N>);
	double operator* (vector<N>);
	vector<N> operator* (double);
	vector<N> operator- (vector<N>);
//	vector operator^ (vector);		// Not needed right now
	double mag ();
	vector<N> operator+= (vector<N>);
	vector<N> operator-= (vector<N>);
	vector<N> operator*= (double);
	bool operator== (vector<N>);
	template <unsigned int M>
		friend vector<M> operator* (double l, vector<M> a) {
			vector<M> r;
			for (int i=0;i<M;i++)
				r.basis[i]=a.basis[i]*l;
			return r;
		}
	vector<N> operator/ (double);
};


But it's still not working for me. In one place I have the following code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
template <int N>
void atom<N>::move(double tstep, vector<N> g, vector<N> Ef, vector<N> Bf) {
	particle<N>::k+=g*(mass*tstep/GSL_CONST_MKSA_PLANCKS_CONSTANT_HBAR);
	vector<N> delv = groupv(particle<N>::k) - particle<N>::v;
	vector<N> a = delv/tstep;
	particle<N>::r += (particle<N>::v*tstep + 0.5*a*(tstep*tstep));
	particle<N>::updateEv();
	for(int i=0;i<N;i++)
		Ef.basis[i]=Bf.basis[i]=0;
}


template class atom<1>;
template class atom<2>;
template class atom<3>;


In the above code, the line where I have g*(mass*tstep/GSL_CONST_MKSA_PLANCKS_CONSTANT_HBAR) works fine, but the line with 0.5*a*(tstep*tstep)) doesn't work. This is the functionality I am trying to achieve using the friend function. Of course, I could cut the crap and simply divide by 2, which is what I do to let it compile and let me work go on, but I wonder what happened to the function I wrote and would like to have all features enabled.

Thanks for helping.
Last edited on
Ok I got it. Sorry. Here is what I had to finally do:


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
template <int N>
class vector {
public:
	double basis[N];
public:
	vector<N>(){for(int i=0;i<N;i++)basis[i]=0;}
	vector<N>(double values[N]) {for(int i=0;i<N;i++)basis[i]=values[i];}
	vector<N> operator= (vector<N>);
	vector<N> operator+ (vector<N>);
	double operator* (vector<N>);
	vector<N> operator* (double);
	vector<N> operator- (vector<N>);
//	vector operator^ (vector);		// Not needed right now
	double mag ();
	vector<N> operator+= (vector<N>);
	vector<N> operator-= (vector<N>);
	vector<N> operator*= (double);
	bool operator== (vector<N>);
	friend vector<N> operator* (double l, vector<N> a) {
		vector<N> r;
		for (int i=0;i<N;i++)
			r.basis[i]=a.basis[i]*l;
		return r;
	}
	vector<N> operator/ (double);
};


Thanks a lot for the help. Worked like a charm.
Topic archived. No new replies allowed.