Showing posts with label Templates. Show all posts
Showing posts with label Templates. Show all posts

Tuesday, 22 February 2011

A generic sort program with 'functors' and 'templates'

Picked up this question from here and made a program out of it. It may be a good idea to quickly brush functors and templates if required.

The program sorts the input Vector provided regardless of the type.




//Program tested on Microsoft Visual Studio 2008 - Zahid Ghadialy
#include <iostream>
#include <vector>
#include <string>
#include <algorithm>

using namespace
std;

class
Int
{

public
:
Int() {x_ = 0;}
Int(const int &x) {x_ = x;}
int
getID (void) {return x_;}
int
x_;
};


class
Str
{

public
:
Str() {x_ = "";}
Str(const string &x) {x_ = x;}
string getID (void) {return x_;}
string x_;
};


template
<typename Object> class Comparator {
public
:
bool
operator()(const Object &o1, const Object &o2) const
{

return
(const_cast<Object&>(o1).getID() < const_cast<Object&>(o2).getID());
}


bool
operator()(const Object *o1, const Object *o2) const {
return
(o1->getID() < o2->getID());
}
};


template
<typename VecObject> void Display(VecObject v)
{

VecObject::iterator it;
for
(it = v.begin(); it != v.end(); ++it)
{

cout<<it->getID()<<", ";
}

cout<<endl;
}


int
main()
{

vector<Int> objects1;
objects1.push_back(Int(3));
objects1.push_back(Int());
objects1.push_back(Int(77));

//print the output
cout<<"objects1 before sort = ";
Display(objects1);
std::sort(objects1.begin(), objects1.end(), Comparator<Int> ());
cout<<"objects1 after sort = ";
Display(objects1);

std::vector<Str> objects2;
objects2.push_back(Str("Hello Hello"));
objects2.push_back(Str("apple?"));
objects2.push_back(Str());
objects2.push_back(Str("1 Jump"));

//print the output
cout<<"objects2 before sort = ";
Display(objects2);
std::sort(objects2.begin(), objects2.end(), Comparator<Str> ());
cout<<"objects2 after sort = ";
Display(objects2);

return
0;
}




The output is as follows:
Image

Tuesday, 11 August 2009

Functions returning void

C++ truths discusses an interesting interview question:

"Can you write a return statement in a function that returns void?" The answer is "Yes! You can return void!"

The following is a simple program picked up from the same blog and modified showing a function returning void



//Program tested on Microsoft Visual Studio 2008 - Zahid Ghadialy
//This is a simple example of a function returning void
#include<iostream>

using namespace
std;

static
void foo (void)
{

cout<<"foo() called"<<endl;
}

static
void bar (void)
{

cout<<"bar() called"<<endl;
return
foo(); // Note this return statement.
}
int
main ()
{

cout<<"main() called"<<endl;
bar();
return
0;
}


The output is as follows:

Image

This feature is very useful in case of Templates. Lets write a simple program that uses Templates:


//Program tested on Microsoft Visual Studio 2008 - Zahid Ghadialy
//This is a simple example of a Template returning void
#include<iostream>
//#include <typeinfo> - Some compilers may need this

using namespace
std;

template
<class T> T FOO (void)
{

cout<<"T FOO() called with T = "<<typeid(T).name()<<endl;
return
T(); // Default construction
}

template
<class T> T BAR (void)
{

cout<<"T BAR() called with T = "<<typeid(T).name()<<endl;
return
FOO<T>(); // Syntactic consistency. Same for int, void and everything else.
}

int
main (void)
{

cout<<"main() called"<<endl;
BAR<void>();
BAR<int>();
BAR<char>();
}



The output is as follows:

Image

Monday, 20 April 2009

An example of using Typename with Templates

Typename is used with templates where the type is unknown. Use the keyword typename if you have a qualified name that refers to a type and depends on a template parameter. Only use the keyword typename in template declarations and definitions.


//Program tested on Microsoft Visual Studio 2008 - Zahid Ghadialy
//This program shows an how to use typename with templates
//Example from
//http://www.deitel.com/articles/cplusplus_tutorials/20060428/index.html
#include<iostream>

//using namespace std; //No need to use the whole namespace std
using std::cout;
using
std::endl;

// function template printArray definition
template<typename T>
void
printArray( const T *array, int count )
{

for
( int i = 0; i < count; i++ )
{

cout << array[ i ] << " ";
}

cout << endl;
}
// end function template printArray

int
main()
{

const
int ACOUNT = 5; // size of array a
const int BCOUNT = 7; // size of array b
const int CCOUNT = 6; // size of array c

int
a[ ACOUNT ] = { 1, 2, 3, 4, 5 };
double
b[ BCOUNT ] = { 1.1, 2.2, 3.3, 4.4, 5.5, 6.6, 7.7 };
char
c[ CCOUNT ] = "HELLO"; // 6th position for null

cout << "Array a contains:" << endl;
// call integer function-template specialization
printArray( a, ACOUNT );

cout << "Array b contains:" << endl;
// call double function-template specialization
printArray( b, BCOUNT );

cout << "Array c contains:" << endl;
// call character function-template specialization
printArray( c, CCOUNT );

return
0;
}



Note in the above example you could have replaced 'typename' with 'class' and obtain the same results. Compare this with our basic template example discussed before.

The output of the program is as follows:
Image

Monday, 2 March 2009

Example of C++ Templates

Program to show how templates work in a very simple way:




//Program tested on Microsoft Visual Studio 2008 - Zahid Ghadialy
//Note this program shows Template example

#include<iostream>

using namespace
std;

template
<class T> class Arith
{

public
:
T Add(T a, T b)
{

return
a + b;
}
};


template
<class T, class U> class ArithNew
{

public
:
T Add(T a, U b)
{

return
(T)(a + b); //the return type is casted otherwise a warning will be generated
}
};


int
main(void)
{

Arith<int> ar1;
int
x = ar1.Add(3, 5);
cout<<"x = "<<x<<endl;

Arith<double> ar2;
double
y = ar2.Add(3.3, 1.2);
cout<<"y = "<<y<<endl;

//Arith<int> ar3;
//double z = ar3.Add(3, 1.2);
//cout<<"z = "<<z<<endl;
//The above is possible but loss of data and no flexibility. Cant mix two types

ArithNew<double, int> ar4;
double
xx = ar4.Add(5.5, 2);
cout<<"xx = "<<xx<<endl;

//reversing the same as above
ArithNew<int, double> ar5;
int
yy = ar5.Add(2, 5.5); //works without warning because of return type being casted otherwise warning
cout<<"yy = "<<yy<<endl;

return
0;
}