Convert each function to a function template

I am assigned this program by my instructor and he wants me to convert the function to function template. I do not know how to do that. Please help me get good grades in final. Thankyou. and I am just a beginner in C++ so it would be great if you can show final steps.



#include <iostream>
#include <sstream>
#include <fstream>
using namespace std;
#include "Test.h"
struct char_list
{
char head;
char_list* tail;
};
char_list* cons(char, char_list*);
char_list* cs116();
void print_list(char_list*);
char_list* stream_to_list(istream&);
// return a list that is a subset of the 2nd parameter
// only allow those characters which pass the filter test
// determined by the boolean function (1st parameter)
char_list* filter(bool(*)(char),char_list*);
bool is_digit(char c) { return isdigit(c); }
int length(char_list*);
char_list* oop();
char_list* append(char_list*, char_list*);

class TestFP : public TestSuite::Test
{
public:
void run()
{
ostringstream oss;
ostream save_buffer(cout.rdbuf()); //current ostream buffer
cout.rdbuf(oss.rdbuf()); // redirection to stringstream

// testcase #1 check print_list and cs116() and cons
print_list(cs116());
cerr << "<" << oss.str() << ">" << endl;
test_(oss.str()=="cs116");

// testcase #2 check stream_to_list(cin)
/*
oss.str("");
print_list(stream_to_list(cin)); //assume user enters "OOP"
cerr << "<" << oss.str() << ">" << endl;
test_(oss.str()=="OOP");
*/

// testcase #3 check stream_to_list from a stringstream
oss.str("");
istringstream iss("OOP");
print_list(stream_to_list(iss));
cerr << "<" << oss.str() << ">" << endl;
test_(oss.str()=="OOP");

// testcase #4 check stream_to_list from a file
oss.str("");
ifstream ifs("cs116.txt");
print_list(stream_to_list(ifs));
cerr << "<" << oss.str() << ">" << endl;
test_(oss.str()=="Programming");

// testcase #5 check filter - expect to return "116"
oss.str("");
print_list(filter(is_digit,cs116()));
cerr << "<" << oss.str() << ">" << endl;
test_(oss.str()=="116");

//testcase #6 check length - expect to return 5
oss.str("");
cout << length(cs116()); // assume user enter "OOP"
cerr << "<" <<oss.str() << ">" << endl;
test_(oss.str() =="5");

// testcase #7 check append "OOP" to "cs116"
//expect it to return "cs116OOP"
oss.str("");
print_list(append(oop(),cs116()));
cerr << "<" << oss.str() << ">" << endl;
test_(oss.str()=="cs116OOP");



// restore the original buffer
cout.rdbuf(save_buffer.rdbuf());
}
};
int main()
{
TestFP t;
t.run();
t.report();
}
char_list* oop()
{
return cons('O', cons('O',cons('P',NULL)));
}
char_list* append(char_list* list2, char_list* list1)
{
if(list1) return cons (list1->head,append(list2,list1->tail));
else return list1;
}
int length(char_list* list)
{
if(list) return length (list->tail)+1;
else return 0;
}
// return a list that is a subset of the 2nd parameter
// only allow those characters which pass the filter test
// determined by the boolean function (1st parameter)
char_list* filter(bool(*p)(char),char_list* list)
{
if(list and p(list->head))
return cons(list->head,filter(p,list->tail));
else if(list) return filter(p, list->tail);
else return false;
}
char_list* stream_to_list(istream& in)
{
char c;
if(in >> c) return cons(c,stream_to_list(in));
}
void print_list(char_list* list)
{

cout << list->head;
if(list->tail) print_list(list->tail);
}
char_list* cs116()
{
return cons('c',cons('s',cons('1',cons('1',cons('6',NULL)))));
}
char_list* cons(char h, char_list* t)
{
char_list* list = new char_list;
list->head = h;
list->tail = t;
return list;
}
Templates are a mechanism for letting the compiler fill in missing information. You can see this as a smart copy-pasting function, by which the compiler generates the source code it needs to compile.

A function template example:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
template <typename T>
T giveback(T t)
{
    return t;
}

int main()
{
    MyClass mc;

    giveback<int>(10); // 0, same as...
    giveback(10); // 1
    giveback('A'); // 2
    giveback<MyClass>(mc); // 3
}
// code generated for 0 and 1
int giveback(int t)
{
    return t;
}

// code generated for 2
char giveback(char t)
{
    return t;
}

// code generated for 3
MyClass giveback(MyClass t)
{
    return t;
}


A class template example:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
template <typename IntType>
class MyArray
{
private:

    IntType arr[100];

public:

    const IntType * get_arr() const
    {
        return arr;
    }
};

int main()
{
    MyArray<int> mai;
}
// class code generated
class MyArray
{
private:

    int arr[100];

public:

    const int * get_arr() const
    {
        return arr;
    }
};


The sensible use of templates is writing containers and algorithms.

For example, std::vector is a class template and is also a container.
You need to specify what type of elements you want it to store before you can use it, hence:

1
2
3
4
5
6
#include <vector>

// ...

std::vector<char> vector_of_chars;
std::vector<int> vector_of_ints;


Algorithms, as seen in the functions template example, are written once then used the same way for different types (of containers).

See the algorithm library of C++ for a nice collection:
http://www.cplusplus.com/reference/algorithm/

Example of the std::sort() function template:

1
2
3
4
5
6
#include <algorithm>

// ...

std::sort(vector_of_chars.begin(), vector_of_chars.end());
std::sort(vector_of_ints.begin(), vector_of_ints.end());


The not-so-sensible usage is called Template Metaprogramming (TMP) and it was discovered when people saw that you can get the compiler to fill in things other than just types, such as numbers.
http://en.wikipedia.org/wiki/Template_metaprogramming

By using TMP you abuse (I'd say misuse) the compiler to generate a simplified program, tailored to data known at compile-time (and not at runtime).

Anyway, what was your question again?
http://www.cplusplus.com/doc/tutorial/templates/#class_templates

Also next time use code tags, please.
http://www.cplusplus.com/articles/jEywvCM9/
Last edited on
Topic archived. No new replies allowed.