The Practice of Programming, CSIE@NTNU, Fall, 2010
Function Pointers, Functors,& C/C++ Search & Sort
Instructor: Tsung-Che [email protected]
Department of Computer Science and Information EngineeringNational Taiwan Normal University
“Templates & STL,”The Practice of Programming, CSIE@NTNU, 2010
Write a simple sort function (bubble or selection sort is okay) forsorting an array/vector of CStudent objects inascending order of the id.
You can write the expression
stu[i].id < stu[j].id
directly in the sort function.But, what if I want another comparison criterion?
Try to provide an operator < for CStudent.
Exercise
struct CStudent{
int id,score;
std::string name;};
“Templates & STL,”The Practice of Programming, CSIE@NTNU, 2010
Now I want to sort the students in ascending order ofthe id in some cases and in ascending order of thescore in other cases. What will you do?
Next, I find that in a special case I need to sort thedata in ascending order of the name.
Should you code another sort function(if you write the previous two functions separately, sort1() & sort2())
or should you modify the existing code(if you pass a function identifier like an integer, sort(…, 1) & sort(…, 2))?
Exercise
“Templates & STL,”The Practice of Programming, CSIE@NTNU, 2010
Function Pointers
void print_simple(int a, double b){
cout << a << ' ' << b << endl;}// ---------------------------------------------------------void print_complex(int c, double d){
cout << '[' << c << "] [" << d << ']' << endl;}// ---------------------------------------------------------int main (){
void (*function_pointer)(int, double) = &print_simple;
(*function_pointer)(1, 2.5);
function_pointer = &print_complex;
(*function_pointer)(1, 2.5);
return 0;}
Without the parenthesis aroundfunction_pointer, the statement is just adeclaration of a function returning void *.
“Templates & STL,”The Practice of Programming, CSIE@NTNU, 2010
Function Pointerstypedef bool (*CStudentCmp)(const CStudent &lhs, const CStudent &rhs);
//void Sort(CStudent data[], int size,// bool (*fp)(const CStudent &lhs, const CStudent &rhs))void Sort(CStudent data[], int size, CStudentCmp fp){
// somewhere you call (*fp)(data[i], data[j])}
int main (){
CStudent arr[10];
// ...
Sort(arr, 10, &hasSmallerId); cout << "-";Sort(arr, 10, &hasSmallerScore); cout << "=";Sort(arr, 10, &hasSmallerName);
return 0;}
bool hasSmallerId(const CStudent &lhs, const CStudent &rhs){ return lhs.id < rhs.id; }
“Templates & STL,”The Practice of Programming, CSIE@NTNU, 2010
Generic Types
Okay, now I can deal with a variety of comparators forCStudent.
What about CFaculty? A function with a CStudent *parameter cannot accept CFaculty *!
Should we write the sort algorithm again?
In C, the way to accept generic types is through void *. In C++, we have function templates.
“Templates & STL,”The Practice of Programming, CSIE@NTNU, 2010
void *int main (){
CStudent s;CFaculty f;s.id = 123;
CStudent *ps = 0;CFaculty *pf = 0;
//ps = &f;//pf = &s;
void *p;p = &f;p = &s;
ps = (CStudent *)p;
cout << ps->id;
return 0;}
// Incompatible types
// Explicit type conversion
// Both acceptable
“Templates & STL,”The Practice of Programming, CSIE@NTNU, 2010
Libraries for Search & Sort
C: qsort()
#include <stdlib.h>void qsort( void *buf, size_t num, size_t size,
int (*compare)(const void *, const void *));
The qsort() function sorts buf (which contains num items, each of size size) using Quicksort.
The compare function is used to compare the items in buf.
compare should returnnegative if the first argument is less than the second,zero if they are equal, andpositive if the first argument is greater than the second.
qsort() sorts buf in ascending order.
“Templates & STL,”The Practice of Programming, CSIE@NTNU, 2010
Libraries for Search & Sort
C: qsort()#include <stdlib.h>void qsort( void *buf, size_t num, size_t size,
int (*compare)(const void *, const void *));
&data[i]
int main(){
int data[N];// ...qsort(data, N, sizeof(data[0]),
icmp);return 0;
}
int icmp(const void *lhs,const void *rhs) {
int v1 = *(int *)lhs,v2 = *(int *)rhs;
if (v1 < v2) return -1;else if (v1 > v2) return 1;else return 0;
}
data
“Templates & STL,”The Practice of Programming, CSIE@NTNU, 2010
Libraries for Search & Sort
C: qsort()#include <stdlib.h>void qsort( void *buf, size_t num, size_t size,
int (*compare)(const void *, const void *));
int main(){
char *data[N];// ...qsort(data, N, sizeof(data[0]),
scmp);return 0;
}
int scmp(const void *lhs,const void *rhs)
{char *v1 = *(char **)lhs,
*v2 = *(char **)rhs;
return strcmp(v1, v2);}
&data[i]
data
“Templates & STL,”The Practice of Programming, CSIE@NTNU, 2010
Libraries for Search & Sort
C: qsort()#include <stdlib.h>void qsort( void *buf, size_t num, size_t size,
int (*compare)(const void *, const void *));
struct Nameval {char *name;int value;
};typedef struct Nameval Nameval;
int main() {Nameval data[N];// ...qsort(data, N, sizeof(data[0]),
nvcmp);return 0;
}
int nvcmp(const void *lhs,const void *rhs) {
Nameval *v1 = (Nameval *)lhs,*v2 = (Nameval *)rhs;
return strcmp(v1->name, v2->name);}
“Templates & STL,”The Practice of Programming, CSIE@NTNU, 2010
Libraries for Search & Sort
C: bsearch()
#include <stdlib.h>void *bsearch(const void *key,
const void *buf, size_t num, size_t size,int (*compare)(const void *, const void *) );
The bsearch() function searches buf[0] to buf[num-1] for an itemthat matches key, using a binary search.
The function compare should returnnegative if its first argument is less than its second,zero if equal, andpositive if greater.
The items in the array buf should be in ascending order. The return value ofbsearch() is a pointer to the matching item, or NULL if none is found.
“Templates & STL,”The Practice of Programming, CSIE@NTNU, 2010
Exercise
Write a Id-comparator for CStudent.Call qsort() to see if the data are sorted.Call bsearch() to find an existing element and a
non-existing element.
You can sort the data directly. That’s easier. Try to sort an array/vector of CStudent *. That’s
much harder, but it checks if you understand theconcept well and this version is more efficient. (Left asan exercise since the time is not enough today.)
“Templates & STL,”The Practice of Programming, CSIE@NTNU, 2010
Functor
class CHasSmallerId{public:
bool operator()(const CStudent &lhs, const CStudent &rhs){
return lhs.id < rhs.id;}
};
int main (){
CStudent a, b;CHasSmallerId hasSmallerId;
if (hasSmallerId(a, b)){}
return 0;}
“Templates & STL,”The Practice of Programming, CSIE@NTNU, 2010
Functor
class ManyPrototypes{public:
void operator()(int a) { cout << a; }bool operator()(double a, double b) { return a < b; }int operator()(int num1, int num2, int num3){ return num1+num2+num3; }
};
int main (){
ManyPrototypes m;
m(10);if (m(2, 3)){
cout << m(11, 22, 33);}
return 0;}
The functor simulates the functions,but there’s much more since it is aclass!
“Templates & STL,”The Practice of Programming, CSIE@NTNU, 201048
Exercise
Writing a set of simple_sort() function. One supports the operator <.
The second supports a function pointer as the comparator.
The last supports a functor as the comparator.
Use your sort functions to sort CStudent inascending order of id, score, and age. id: operator < score: a function HasSmallerScore() name: a functor CHasSmallerName
“Templates & STL,”The Practice of Programming, CSIE@NTNU, 201049
Exercise
“Templates & STL,”The Practice of Programming, CSIE@NTNU, 201050
Exercise
“Templates & STL,”The Practice of Programming, CSIE@NTNU, 201051
Exercise
“Templates & STL,”The Practice of Programming, CSIE@NTNU, 201052
Exercise
“Templates & STL,”The Practice of Programming, CSIE@NTNU, 201053
Exercise
The Practice of Programming, CSIE@NTNU, Fall, 2010
Function Templates
Instructor: Tsung-Che [email protected]
Department of Computer Science and Information EngineeringNational Taiwan Normal University
“Templates & STL,”The Practice of Programming, CSIE@NTNU, 201055
Motivation
Should we implement find() for everydata type manually?
“Templates & STL,”The Practice of Programming, CSIE@NTNU, 201056
template <typename T, typename V>T find(T start, T end, V key){
while (start != end) {if (*start == key)
break;start++;
}
return start;}
Toward Function Templates
“Templates & STL,”The Practice of Programming, CSIE@NTNU, 2010
template <typename T1, typename T2>void func(T1 v1, T2 v2) { T1 local; ... }
template <typename T1>void func2(T1 *p) { ... }
57
Declarations and Definitions
template <typename T1, class T2>void func3(T1 v, T2 u) { ... }
template <typename Type, typename Type>Type wrong1(Type v1, Type v2) { ... }
template <typename T1, T2>T1 *wrong2(const T2 &v1, const T2 &v2) { ... }
“Templates & STL,”The Practice of Programming, CSIE@NTNU, 201058
Declarations and Definitions
typedef double Type;template <class Type>Type func(Type a, Type b){
Type local;}template <class T>T func2(T a, T b){
typedef double T;}
The global Type is hidden inthe scope of func().
Error: redeclaration of templateparameter
template <class Type>inline Type func(Type a, Type b) { ... }
inline template <class Type> func2(Type a, Type b) { ... }
“Templates & STL,”The Practice of Programming, CSIE@NTNU, 201059
Instantiation
Template instantiation takes place when the functiontemplate is called or when its address is taken.
template <class T, class V>T find(T start, T end, V key){
while (start != end) {if (*start == key)
break;start++;
}
return start;}
int main(){
int A[] = {1, 2, 3},ptr = find(A, A+3, 2);
char * (*charfind)(char *, char *,char) = &find;
}
“Templates & STL,”The Practice of Programming, CSIE@NTNU, 201060
Argument Deduction
When a function template is called, types of templatearguments are determined according to the functionarguments. Note the return value of the function does not participate in
argument deduction.
template <class T>T func(T v1, T v2) { ... }
int main(){
func(10, 10);int num = func(2.3, 3.8); // argument T is “double”func(‘C’, ‘D’);func(“ABCD”, “EFGH”);func(10, 2.3); // argument deduction fails
}
“Templates & STL,”The Practice of Programming, CSIE@NTNU, 201062
Argument Deduction
Type transformationtemplate <class T>T func(T *arr) { ... }
template <class T>T func2(const T *arr) { ... }
int main() {int *p, arr[10];
func(p);func(arr); // array-to-pointer transformation
func2(p); // qualification transformationfunc2(arr); // array-to-pointer & qualification trans.
}
“Templates & STL,”The Practice of Programming, CSIE@NTNU, 201065
Compilation Model
Inclusion modelPut the definitions of function templates in the
header file, just as how we treat inline functions.
Separation model (Few compilers support it.)Put the declaration of function templates in the
header file and definitions in the implementationfile, just as how we treat non-inline functions.
Add “export”at the beginning of the definition ofthe function template.
“Templates & STL,”The Practice of Programming, CSIE@NTNU, 201066
Exercise
Make your simple_sort() functions be functiontemplates so that they can deal with every kind ofdata type as the type supports operator < or acomparing function/functor.
std::sort as a reference
#include <algorithm>
template <typename RandomAccessIterator>void sort(RandomAccessIterator first, RandomAccessIterator last);
template <typename RandomAccessIterator, typename Compare>void sort(RandomAccessIterator first, RandomAccessIterator last,
Compare comp);
“Templates & STL,”The Practice of Programming, CSIE@NTNU, 201067
Exercise
The version that uses operator <
“Templates & STL,”The Practice of Programming, CSIE@NTNU, 201068
Exercise
The version that uses a comparing function/functor
“Templates & STL,”The Practice of Programming, CSIE@NTNU, 201069
Exercise
Now you know what std::sort can do for you andhow it works. Certainly, std::sort realizes more efficient sort
algorithms, not the selection sort in our example.
The concept we learned in this exercise can begeneralized to (almost) all algorithms in C++ STL.
The Practice of Programming, CSIE@NTNU, Fall, 2010
C++ Algorithms
Instructor: Tsung-Che [email protected]
Department of Computer Science and Information EngineeringNational Taiwan Normal University
“Templates & STL,”The Practice of Programming, CSIE@NTNU, 201071
The STL Generic Algorithms
SearchSorting & orderingDeleting & replacingPermutationGenerationNumericRelational
“Templates & STL,”The Practice of Programming, CSIE@NTNU, 201072
Search Algorithms
Search count(), count_if() find(), find_if(), adjacent_find(),find_first_of()
search(), find_end()
Only for sorted range: binary_search() lower_bound(), upperbound(), equal_range()
example: find digits in a sentence
string matching (not really efficient for ACMer)
1 1 2 3 4 4 4 5 6 7 8 9 9 9 10 11 12 12 12 12 13 16
lower_bound(b, e, 4);
upper_bound(b, e, 9);
equal_range(b, e, 12);
“Templates & STL,”The Practice of Programming, CSIE@NTNU, 201073
Sorting & Ordering
Sorting & ordering sort(), stable_sort()
partition(), stable_partition()
nth_element()
partial_sort()
rotate()
reverse()
random_shuffle()
true false
nth_element(b, b+4, e); // 3 1 4 2 5 6 9 7 8
partial_sort(b, b+4, e); // 1 2 3 4 5 9 8 7 6
rotate(b, b+3, e); // 1 1 1 4 5 6 7 8 9 -> 4 5 6 7 8 9 1 1 1
reverse(b, e); // 1 2 3 4 5 6 7 8 9 -> 9 8 7 6 5 4 3 2 1
A New-Year-gift: If you read this line before Jan. 21, send an e-mail to me immediately and write a 200-word summary of your opinion about this course. You will be rewarded by 2 points in the final score. Donot tell others. The gift will be withdrawn if the number of e-mails is unexpectedly large.
“Templates & STL,”The Practice of Programming, CSIE@NTNU, 201074
Deleting & Replacing
Deleting & replacing remove(), remove_if() replace(), replace_if() unique() swap()
Sorted data are suggested.
Note. The removed elements are not destroyed.
“Templates & STL,”The Practice of Programming, CSIE@NTNU, 201075
Permutation Algorithms
Permutation next_permutation() prev_permutation()
Useful for solving combinatorial problems in a brute-force way.
“Templates & STL,”The Practice of Programming, CSIE@NTNU, 201076
Generation Algorithms
Generation for_each() fill(), fill_n() generate(), generate_n() transform()
Do something to all elements in the range.
“Templates & STL,”The Practice of Programming, CSIE@NTNU, 201077
STL Algorithms
You can learn their functions easily through theexamples.
Just visit http://www.cplusplus.com/reference/algorithm/
“Templates & STL,”The Practice of Programming, CSIE@NTNU, 201078
Boost Library
“Templates & STL,”The Practice of Programming, CSIE@NTNU, 201079
A Happy Ending of This Course
I am so glad to be the instructor of this course.Hope that all of you have learned more about
writing elegant and efficient C++ code.Please keep practicing what you learned in
this semester.
Wish you have a Happy New Year!