Previous Lecture Lecture 12 Next Lecture

Lecture 12, Thu 11/08

Function Pointers

Function Pointers

Example (using std::transform)

#include <iostream>
#include <string>
#include <algorithm>

using namespace std;

int main() {

	string s = "abcd";
	cout << s << endl;
	transform(s.begin(), s.end(), s.begin(), ::toupper);
	cout << s << endl;
}
// Output:
// abcd
// ABCD
transform(s.begin() + 2, s.end(), s.begin(), ::toupper);
// Output: 
// abcd
// CDcd

Another example defining our own function for the transform function

// Our defined function
int multiplyBy100(int x) { return 100 * x; }

// Function to print contents of the vector
void printVector(vector<int> &v) {
	for (int i = 0; i < v.size(); i++) 
		cout << "v[" << i << "] = " << v[i] << endl;
	cout << "---" << endl;
}

int main() {
	vector<int> v;
	for (int i = 10; i <= 15; i++) {
		v.push_back(i);
	}
	printVector(v);
	transform(v.begin(), v.end(), v.begin(), multiplyBy100); // uses our function
	printVector(v);
	return 0;
}
cout << multiplyBy100 << endl; // warning: prints 1 (but does compile correctly)
cout << reinterpret_cast<void*>(multiplyBy100) << endl; // prints an address of where the multiplyBy100 exists in memory

Example defining function pointers

int main() {
	// Pointer to a function that has an int parameter and returns an int.
	int (*someFunctionPointer)(int); 

	// Assign the address of multiplyBy100 to the function pointer.
	someFunctionPointer = multiplyBy100;

	// ERROR!!, trying to assign an int to a function pointer
	// someFunctionPointer = multiplyBy100(10); 

	// Using the function pointer to call a function.
	// Dereferences the pointer as a function, and then passes the parameter
	// 2 to the function.
	cout << (*someFunctionPointer)(2) << endl;

	// ERROR!! Order of operations dereferences after attempting to call the
	// function
	// cout << *someFunctionPointer(2) << endl;
}

Passing a function to another function as a parameter

Example: Writing a template filter function for a vector

template <class T>
void printVector(vector<T> &v) {
	for (int i = 0; i < v.size(); i++) 
		cout << "v[" << i << "] = " << v[i] << endl;
	cout << "---" << endl;
}

template <class T>
bool notEqual(T x, T y) {
	return x != y;
}

template<class T>
vector<T> filterVector(vector<T> v, T value, bool (*filterFunc)(T, T)) {
	vector<T> result;

	for (int i = 0; i < v.size(); i++) {
		if (filterFunc(v[i], value)) {
			result.push_back(v[i]);
		}
	}
	return result;
}

int main() {
	// vector of strings
	vector<string> v1;
	v1.push_back("s1");
	v1.push_back("s2");
	v1.push_back("s3");
	v1.push_back("s2");
	v1.push_back("s1");
	string remove = "s2";
	vector<string> result1 = filterVector(v1, remove, notEqual);
	printVector(result1);

	// vector of ints
	vector<int> v2;
	v2.push_back(1);
	v2.push_back(2);
	v2.push_back(3);
	v2.push_back(2);
	v2.push_back(1);
	vector<int> result2 = filterVector(v2, 1, notEqual);
	printVector(result2);
	return 0;
}