?
Solved

template function w/ type & non-type parameters

Posted on 2008-06-24
5
Medium Priority
?
535 Views
Last Modified: 2013-12-14
I have the following class definitions:

template<unsigned dim>
class Vector
{ ... };

template<unsigned dim>
class Displacement : public Vector<dim>
{ ... };
template<unsigned dim>
class Velocity : public Vector<dim>
{ ... };
template<unsigned dim>
class Acceleration : public Vector<dim>
{ ... };

etc.

Now I want to overload binary operators +, - , *, /. But I don't want to write member functions for all vector types. (there are too many.) So I wrote the following template function:
      template<typename T, unsigned dim>
      T<dim> operator + (const T<dim> & t0, const T<dim> & t1)                 <<<< C2988 on this line
      {
            T<dim> ret;
            for (int i=0; i<dim; i++)
                  ret[i] = t0[i] + t1[i];
      }
But I get compiler error C2988 (unrecognizable template declaration/definition; Visual Studio Pro 2008). The help page (http://msdn.microsoft.com/en-us/library/f69a8fb8.aspx) is pretty useless.
Is it possible to write template like above (of course, w/o syntax errors) or do I have no choice but to copy-paste for all types derived from Vector<dim>?
0
Comment
Question by:jhshukla
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 4
5 Comments
 
LVL 86

Expert Comment

by:jkr
ID: 21862056
Hmmm, I guess you meant the following:
      template<typename T, unsigned dim>
      T operator + (const T & t0[dim], const T & t1[dim])
      {
            T ret[dim];
            for (int i=0; i<dim; i++)
                  ret[i] = t0[i] + t1[i];
      }

Open in new window

0
 
LVL 9

Author Comment

by:jhshukla
ID: 21862464
no I did not mean that.
The code you suggested would create (well, it is reference. so technically not "create" but let me use that term here anyways) an array of T's. I want one variable of type T<dim>.

and if [] inside the function confused you, it is using overloaded [] operator. to be more elaborate this is how Vector class is defined:
	template<unsigned dim>
	class Vector
	{
	public:
		Vector(double *init = NULL)
		{
			if (init == NULL)
				memset(components, 0, sizeof(components));
			else
				memcpy(components, init, sizeof(components));
		}
		~Vector(void) {}
 
		inline double operator[](int i) const { return components[i]; }
		inline double & operator[](int i) { return components[i]; }
 
/*
		these commented out functions are the ones I want to mimic using
		templates
		inline Vector<dim> operator/(double div) const
		{
			Vector<dim> ret;
			for (int i=0; i<dim; i++)
				ret[i] = components[i] / div;
		}
		inline Vector<dim> operator*(double mul) const
		{
			Vector<dim> ret;
			for (int i=0; i<dim; i++)
				ret[i] = components[i] * mul;
		}
 
		inline Vector<dim> operator+(Vector<dim> that) const
		{
			Vector<dim> ret;
			for (int i=0; i<dim; i++)
				ret[i] = components[i] + that[i];
		}
		inline Vector<dim> operator-(Vector<dim> that) const
		{
			Vector<dim> ret;
			for (int i=0; i<dim; i++)
				ret[i] = components[i] - that[i];
		}
*/
		inline double MagnitudeSq() const
		{ return dot(*this, *this); }
		inline double Magnitude() const
		{ return sqrt(MagnitudeSq()); }
		inline static double dot(const Vector<dim> & v0, const Vector<dim> & v1)
		{
			double accum = 0;
			for (int i=0; i<dim; i++)
				accum += v0[i]*v1[i];
			return accum;
		}
 
	private:
		double components[dim];
	};

Open in new window

0
 
LVL 9

Author Comment

by:jhshukla
ID: 21862492
Forgot to mention that T will always be a derived class of Vector<dim>.

I expect to be able to use the template like this:
Displacement<3> d1, d2, d3;
d3 = d1 + d2;

The addition statement will cause the following function to be instantiated:
Displacement<3> operator + (const Displacement<3> &t0, const Displacement<3> &t1)
{ ... }

I found something called "template template parameter." no, it is not a typo. the word "template" is repeated. but cannot get it to work. e.g.
http://publib.boulder.ibm.com/infocenter/macxhelp/v6v81/topic/com.ibm.vacpp6m.doc/language/ref/clrc16template_template_parameters.htm
and with some explanation: http://www.informit.com/articles/article.aspx?p=376878

I modified the function template after reading InformIT article but I get even more errors now:
      template<template<unsigned dim> T>
      T operator + (const T & t0, const T & t1)
      {
            T ret;
            for (int i=0; i<dim; i++)
                  ret[i] = t0[i] + t1[i];
      }
0
 
LVL 9

Author Comment

by:jhshukla
ID: 21862571
update. I made a mistake above. it is supposed to be the following:
      template<template<unsigned dim> class T>
      T operator + (const T & t0, const T & t1)                   <<< C3205 here
      {
            T ret;
            for (int i=0; i<dim; i++)
                  ret[i] = t0[i] + t1[i];
      }

however, now I am getting the error: "C3205: argument list for template template parameter 'T' is missing."
If I replace it with T<dim> it says "error C2065: 'dim' : undeclared identifier."
      template<template<unsigned dim> class T>
      T<dim> operator + (const T<dim> & t0, const T<dim> & t1)
      {
            T<dim> ret;
            for (int i=0; i<dim; i++)
                  ret[i] = t0[i] + t1[i];
      }
0
 
LVL 9

Accepted Solution

by:
jhshukla earned 0 total points
ID: 21862696
phew. finally figured it out.

found clue here: http://hal.iwr.uni-heidelberg.de/lehre/prosem-06/Popov.pdf
scroll to p11

// This works:
	template<template<unsigned> class T, unsigned dim>
	T<dim> operator + (const T<dim> & t0, const T<dim> & t1)
	{
		T<dim> ret;
		for (int i=0; i<dim; i++)
			ret[i] = t0[i] + t1[i];
		return ret;
	}
 
// This should work too (template parameters are switched. nothing big):
	template<unsigned dim, template<unsigned> class T>
	T<dim> operator + (const T<dim> & t0, const T<dim> & t1)
	{
		T<dim> ret;
		for (int i=0; i<dim; i++)
			ret[i] = t0[i] + t1[i];
		return ret;
	}
 
// after this we can use statements like:
Displacement<3> d1, d2, d3;
d3 = d1 + d2;
Velocity<2> v1, v2, v3;
v1 = v2 + v3;

Open in new window

0

Featured Post

What does it mean to be "Always On"?

Is your cloud always on? With an Always On cloud you won't have to worry about downtime for maintenance or software application code updates, ensuring that your bottom line isn't affected.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Introduction This article is a continuation of the C/C++ Visual Studio Express debugger series. Part 1 provided a quick start guide in using the debugger. Part 2 focused on additional topics in breakpoints. As your assignments become a little more …
For most people, the WrapPanel seems like a magic when they switch from WinForms to WPF. Most of us will think that the code that is used to write a control like that would be difficult. However, most of the work is done by the WPF engine, and the W…
The viewer will be introduced to the technique of using vectors in C++. The video will cover how to define a vector, store values in the vector and retrieve data from the values stored in the vector.
The viewer will be introduced to the member functions push_back and pop_back of the vector class. The video will teach the difference between the two as well as how to use each one along with its functionality.

764 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question