Posts Tagged ‘template’

Posted by kent at 20 October 2010

Category: c++

Tags: , , , , ,

This is a reminder to myself.

To sort a collection of non-POD types (not Plain Old Data) with STL we need to tell it how to sort these objects.

To the std::sort method we simply supply a predicate! It’s just a method taking 2 arguments of that type and apply our logic to tell if the first argument is lesser than the last argument. With templates it becomes a little more complex, but still it’s very simple when you know how it works.

Here is some sample code:

#include <iostream>     // Provides cout
#include <vector>       // Provides our basic container
#include <algorithm>    // Provides std::sort

using namespace std;

// Structures I'll sort with 1 template function
//
//
struct A
{
    A(size_t i, size_t t) : id(i), time(t), other_data(false){}
    size_t  id;
    size_t  time;
    bool    other_data;
};

struct B
{
    B(size_t i, size_t t) : id(i), time(t), other_data("string data"){}
    size_t  id;
    size_t  time;
    string  other_data;
};

struct C
{
    C(size_t i, size_t t) : id(i), time(t), other_data("character array data"){}
    size_t  id;
    size_t  time;
    char*   other_data;
};

// Our predicate
//
template<typename CLASS>
bool timeSortPredicate( const CLASS &a, const CLASS &b )
{
    return a.time < b.time;
}

template<typename CLASS>
bool idSortPredicate( const CLASS &a, const CLASS &b )
{
    return a.id < b.id;
}

// Our collection printer
//
template<typename CLASS>
void print( const CLASS &c )
{
    typedef typename CLASS::const_iterator cit;

    for ( cit it = c.begin(); it != c.end(); ++it )
    {
        cout << it->id << " " << it->time << endl;
    }
}

int main()
{
    // Construct the objects ... tedious I know
    A a1(1,15), a2(2,20),   a3(3,14);
    B b1(3,4),  b2(2,10),   b3(1,12);
    C c1(11,0), c2(12,0),   c3(13,0);

    // Construct collections
    vector<A> alist;
    alist.push_back(a1);
    alist.push_back(a2);
    alist.push_back(a3);

    vector<B> blist;
    blist.push_back(b1);
    blist.push_back(b2);
    blist.push_back(b3);

    vector<C> clist;
    clist.push_back(c1);
    clist.push_back(c2);
    clist.push_back(c3);

    // Print stuff
    cout << "Collection A" << endl;
    print(alist);

    cout << "Collection B" << endl;
    print(blist);

    cout << "Collection C" << endl;
    print(clist);

    cout << "Sorting collections by time" << endl;

    sort(alist.begin(), alist.end(), timeSortPredicate<A> );
    sort(blist.begin(), blist.end(), timeSortPredicate<B> );
    sort(clist.begin(), clist.end(), timeSortPredicate<C> );

    // Print stuff
    cout << "Collection A" << endl;
    print(alist);

    cout << "Collection B" << endl;
    print(blist);

    cout << "Collection C" << endl;
    print(clist);

    cout << "Sorting collections by id" << endl;

    sort(alist.begin(), alist.end(), idSortPredicate<A> );
    sort(blist.begin(), blist.end(), idSortPredicate<B> );
    sort(clist.begin(), clist.end(), idSortPredicate<C> );

    // Print stuff
    cout << "Collection A" << endl;
    print(alist);

    cout << "Collection B" << endl;
    print(blist);

    cout << "Collection C" << endl;
    print(clist);

    return 0;
}

Compile with:

g++ sortpredicate.cpp -o sortpredicate

The output should be:

Collection A
1 15
2 20
3 14
Collection B
3 4
2 10
1 12
Collection C
11 0
12 0
13 0
Sorting collections by time
Collection A
3 14
1 15
2 20
Collection B
3 4
2 10
1 12
Collection C
11 0
12 0
13 0
Sorting collections by id
Collection A
1 15
2 20
3 14
Collection B
1 12
2 10
3 4
Collection C
11 0
12 0
13 0
VN:F [1.9.13_1145]
Rating: 0.0/5 (0 votes cast)
Share

Posted by Tatyana at 2 March 2010

Category:

Tags: , , , , , ,

Templates in C++ are the way functions and classes operate with generic types. This allows a function or class to work on many different data types without being rewritten for each one [wiki].

Note that there is a difference between class template and a template class: class template is a template used to generate template classes. You cannot declare an object of a class template. Template class is an instance of a class template.

Here we are going to look at 3 main clas templates that are very useful in game and 3D design: Point, Vector and Matrix class templates.

Point and Point3D:

Here is how a simple Point template will look like in C++. This template is constructed to support multiple dimensions like Point2D, 3D and so on:

template <class T, int n> class Point {
protected:
	T mat[n];
	 void cp(const Point<T,n> &p)
    {
		memcpy(mat, p.mat, n*sizeof(T) );
	 }

    void cp(const T p[n])
    {
		memcpy(mat, p, n*sizeof(T) );
	}

    void cp(const T &val)
    {
		for (int i=0; i<n; i++)
			mat[i] = val;
    }

public:
	// new constructor
	Point(const T pt[n])
	{
		cp(pt);
	}

	// copy constructor
	Point(const Point<T,n> &cp)
	{
		this->cp(cp);
	}

	// default constructor
	Point()
	{
		for (int i=0; i<n; i++)
			mat[i] = 0;
	}
	virtual ~Point(void) {};
};

Templates are of great utility to programmers in C++, especially when combined with multiple inheritance and operator overloading. Here vi can add multiple operator overloading functions to our Point class template, for example addition:

        //Point + some value
	Point<T,n> &operator+=(const T &val)
    {
		for (int i=0; i<n; i++)
			mat[i] += val;

		return (*this);
    }

    //sum of two Points
    Point<T,n> &operator+=(Point<T,n> &pt)
    {
		for (int i=0; i<n; i++)
			mat[i] += pt[i];

		return (*this);
    }

A Point3D class template will look like this:

template <class T> class Point3D : public Point<T,3> {
public:
	Point3D() : Point<T,3>() {};

	Point3D(const Point3D<T> &p) : Point<T,3>(p) {
		for (int i=0; i<3; i++)
		mat[i] = p.mat[i];
	}
	Point3D( const T px, const T py, const T pz)
	{
		mat[0]=px; mat[1]=py; mat[2]=pz;
	}
};

An example of how we can use it is a motion programming:

	Point3D<float> EulerAngle(float sensitivity, double x, double y, double z) {
		return Point3D<float> (
				sensitivity*cos(z),
				sensitivity*sin(z),
				0
		);
	}
VN:F [1.9.13_1145]
Rating: 0.0/5 (0 votes cast)
Share