8 template functions
Transcript of 8 template functions
![Page 1: 8 template functions](https://reader033.fdocuments.in/reader033/viewer/2022041701/62536c0b19184b608f65bd34/html5/thumbnails/1.jpg)
Template Functions
How do we write functions that are data type-agnostic?
CS 106L, Fall ‘21
![Page 2: 8 template functions](https://reader033.fdocuments.in/reader033/viewer/2022041701/62536c0b19184b608f65bd34/html5/thumbnails/2.jpg)
• Recap: iterators and template classes
• Generic programming
• Template functions
• Type deduction
• rvalues, lvalues, and references
• Template metaprogramming (TMP)
• Type traits
• Template function practice (motivating lambdas)
Today’s agenda
2
![Page 3: 8 template functions](https://reader033.fdocuments.in/reader033/viewer/2022041701/62536c0b19184b608f65bd34/html5/thumbnails/3.jpg)
• Iterators are objects that point to elements inside containers.
• Each STL container has its own iterator, but all of these iterators exhibit a similar behavior!
• Generally, STL iterators support the following operations:
STL Iterators
3
std::set<type> s = {0, 1, 2, 3, 4};std::set::iterator iter = s.begin(); // at 0++iter; // move iterator by 1 spot; at 1*iter; // get element at iterator; 1(iter != s.end()); // can compare iterator equalityauto second_iter = iter; // "copy construction"
Iterator documentation: https://www.cplusplus.com/reference/iterator/
![Page 4: 8 template functions](https://reader033.fdocuments.in/reader033/viewer/2022041701/62536c0b19184b608f65bd34/html5/thumbnails/4.jpg)
Looping over collections
4
std::set<int> set{3, 1, 4, 1, 5, 9}; for (initialization; termination condition; increment) {const auto& elem = retrieve element;cout << elem << endl;
}
std::map<int> map{{1, 6}, {1, 8}, {0, 3}, {3, 9}}; for (initialization; termination condition; increment) {const auto& [key, value] = retrieve element at index; // structured binding!cout << key << ":" << value << ", " << endl;
}
How do we access and print elements in collections?
![Page 5: 8 template functions](https://reader033.fdocuments.in/reader033/viewer/2022041701/62536c0b19184b608f65bd34/html5/thumbnails/5.jpg)
Looping over collections
5
How do we access and print elements in collections?
std::set<int> set{3, 1, 4, 1, 5, 9}; for (auto iter = set.begin(); iter != set.end(); ++iter) {const auto& elem = *iter;cout << elem << endl;
}
std::map<int> map{{1, 6}, {1, 8}, {0, 3}, {3, 9}}; for (auto iter = map.begin(); iter != map.end(); ++iter) {const auto& [key, value] = *iter; // structured binding!cout << key << ":" << value << ", " << endl;
}
![Page 6: 8 template functions](https://reader033.fdocuments.in/reader033/viewer/2022041701/62536c0b19184b608f65bd34/html5/thumbnails/6.jpg)
A class that is parametrized over some number of types.
A class that is comprised of member variables of a general type/types.
Template Classes
6
template<class valueType>RealVector<valueType>::RealVector(){ elems = new valueType[kInitialSize]; logical_size = 0; array_size = kInitialSize;}
template<class valueType> class RealVector {public: //type aliases: this is how the iterator works! using const_iterator = const valueType*;
//initial size for our rev RealVector(size_t n, const valueType& val); //destructor ~RealVector();…
![Page 7: 8 template functions](https://reader033.fdocuments.in/reader033/viewer/2022041701/62536c0b19184b608f65bd34/html5/thumbnails/7.jpg)
So why did we take a break from the STL?
7
Containers Iterators
Functions Algorithms
Classes and Template Classes!
![Page 8: 8 template functions](https://reader033.fdocuments.in/reader033/viewer/2022041701/62536c0b19184b608f65bd34/html5/thumbnails/8.jpg)
8
Generic ProgrammingWriting reusable, unique code with no duplication!
![Page 9: 8 template functions](https://reader033.fdocuments.in/reader033/viewer/2022041701/62536c0b19184b608f65bd34/html5/thumbnails/9.jpg)
• Allow data types to be parameterized (C++ entities that work on any datatypes)
• Template classes achieve generic classes
• What about functions?
• How can we write methods that work on any data type?
Generic C++
9
![Page 10: 8 template functions](https://reader033.fdocuments.in/reader033/viewer/2022041701/62536c0b19184b608f65bd34/html5/thumbnails/10.jpg)
Let's write a function to get the min of two ints!
10
int myMin(int a, int b) {return a < b ? a : b;
}
![Page 11: 8 template functions](https://reader033.fdocuments.in/reader033/viewer/2022041701/62536c0b19184b608f65bd34/html5/thumbnails/11.jpg)
int myMin(int a, int b) {return a < b ? a : b;
}
Let's write a function to get the min of two ints!
11
if condition return if true
return if false
sidenote: ternary operators
![Page 12: 8 template functions](https://reader033.fdocuments.in/reader033/viewer/2022041701/62536c0b19184b608f65bd34/html5/thumbnails/12.jpg)
Let's write a function to get the min of two ints!
12
int myMin(int a, int b) {return a < b ? a : b;
}
// equivalently,int myMin(int a, int b) {if (a < b) {return a;
}return b;
}
if condition return if true
return if false
sidenote: ternary operators
![Page 13: 8 template functions](https://reader033.fdocuments.in/reader033/viewer/2022041701/62536c0b19184b608f65bd34/html5/thumbnails/13.jpg)
Can we handle different types?
13
int myMin(int a, int b) {return a < b ? a : b;
}
int main() {auto min_int = myMin(1, 2); auto min_name = myMin("Sathya", "Frankie");
}
![Page 14: 8 template functions](https://reader033.fdocuments.in/reader033/viewer/2022041701/62536c0b19184b608f65bd34/html5/thumbnails/14.jpg)
int myMin(int a, int b) {return a < b ? a : b;
}
int main() {auto min_int = myMin(1, 2); // 1auto min_name = myMin("Sathya", "Frankie");
}
Can we handle different types?
14
![Page 15: 8 template functions](https://reader033.fdocuments.in/reader033/viewer/2022041701/62536c0b19184b608f65bd34/html5/thumbnails/15.jpg)
Can we handle different types?
15
int myMin(int a, int b) {return a < b ? a : b;
}
int main() {auto min_int = myMin(1, 2); // 1auto min_name = myMin("Sathya", "Frankie"); // error!
}
![Page 16: 8 template functions](https://reader033.fdocuments.in/reader033/viewer/2022041701/62536c0b19184b608f65bd34/html5/thumbnails/16.jpg)
One solution: overloaded functions
16
int myMin(int a, int b) {return a < b ? a : b;
}
// exactly the same except for typesstd::string my_min(std::string a, std::string b) {return a < b ? a : b;
}
int main() {auto min_int = myMin(1, 2); // 1auto min_name = myMin("Sathya", "Frankie"); // Frankie
}
Overloading is having multiple functions of the same name, but with different return types and parameter types!
![Page 17: 8 template functions](https://reader033.fdocuments.in/reader033/viewer/2022041701/62536c0b19184b608f65bd34/html5/thumbnails/17.jpg)
One solution: overloaded functions
17
int myMin(int a, int b) {return a < b ? a : b;
}
// exactly the same except for typesstd::string my_min(std::string a, std::string b) {return a < b ? a : b;
}
int main() {auto min_int = myMin(1, 2); // 1auto min_name = myMin("Sathya", "Frankie"); // Frankie
}
But what about comparing other data types, like doubles, characters, and complex objects?
![Page 18: 8 template functions](https://reader033.fdocuments.in/reader033/viewer/2022041701/62536c0b19184b608f65bd34/html5/thumbnails/18.jpg)
18
Template FunctionsWriting reusable, unique code with no duplication!
![Page 19: 8 template functions](https://reader033.fdocuments.in/reader033/viewer/2022041701/62536c0b19184b608f65bd34/html5/thumbnails/19.jpg)
We can write generic, "template" functions!
19
template <typename Type>Type myMin(Type a, Type b) {return a < b ? a : b;
}
![Page 20: 8 template functions](https://reader033.fdocuments.in/reader033/viewer/2022041701/62536c0b19184b608f65bd34/html5/thumbnails/20.jpg)
We can write generic, "template" functions!
20
template <typename Type>Type myMin(Type a, Type b) {return a < b ? a : b;
}
Declares that the next function declaration is a
template
Specifies that "Type" is some generic type
List of template arguments (types)
![Page 21: 8 template functions](https://reader033.fdocuments.in/reader033/viewer/2022041701/62536c0b19184b608f65bd34/html5/thumbnails/21.jpg)
We can write generic, "template" functions!
21
template <typename Type>Type myMin(Type a, Type b) {return a < b ? a : b;
}
Declares that the next function declaration is a
template
Specifies that "Type" is some generic type
List of template arguments (types)
template <class Type>Type myMin(Type a, Type b) {return a < b ? a : b;
}
Here, "class" is an alternative keyword to
typename. They're 100% equivalent in template function declarations!
![Page 22: 8 template functions](https://reader033.fdocuments.in/reader033/viewer/2022041701/62536c0b19184b608f65bd34/html5/thumbnails/22.jpg)
We can write generic, "template" functions!
22
template <typename Type>Type myMin(Type a, Type b) {return a < b ? a : b;
}
Declares that the next function declaration is a
template
Specifies that "Type" is some generic type
List of template arguments (types)
Scope of template arguments (e.g. Type) is limited to just this one function!
![Page 23: 8 template functions](https://reader033.fdocuments.in/reader033/viewer/2022041701/62536c0b19184b608f65bd34/html5/thumbnails/23.jpg)
We can write generic, "template" functions!
23
template <typename Type=int>Type myMin(Type a, Type b) {return a < b ? a : b;
}
Default value for class template parameter
So how do we use these functions?
![Page 24: 8 template functions](https://reader033.fdocuments.in/reader033/viewer/2022041701/62536c0b19184b608f65bd34/html5/thumbnails/24.jpg)
Calling template functions
24
template <typename Type>Type myMin(Type a, Type b) {return a < b ? a : b;
}
// int main() {} will be omitted from future examples// we'll instead show the code that'd go inside itcout << myMin<int>(3, 4) << endl; // 3
• Template functions can be called (instantiated) implicitly or explicitly
• Template parameters can be explicitly provided or implicitly deduced
Explicit template parameter (Type)
![Page 25: 8 template functions](https://reader033.fdocuments.in/reader033/viewer/2022041701/62536c0b19184b608f65bd34/html5/thumbnails/25.jpg)
Calling template functions
25
template <typename T, typename U>auto smarterMyMin(T a, U b) {return a < b ? a : b;
}
// int main() {} will be omitted from future examples// we'll instead show the code that'd go inside itcout << myMin(3.2, 4) << endl; // 3.2
• Template functions can be called (instantiated) implicitly or explicitly
• Template parameters can be explicitly provided or implicitly deduced
Template parameter deduced from function parameters
let compiler deduce return type
![Page 26: 8 template functions](https://reader033.fdocuments.in/reader033/viewer/2022041701/62536c0b19184b608f65bd34/html5/thumbnails/26.jpg)
Let's review r-/lvalues and references
26
bool makeEven (int& x) {// make number even and return whether or not original number was odd.bool wasOdd = x % 2;x *= 2;return wasOdd;
}
int x = 5;bool wasOdd = f(x);
![Page 27: 8 template functions](https://reader033.fdocuments.in/reader033/viewer/2022041701/62536c0b19184b608f65bd34/html5/thumbnails/27.jpg)
Let's review r-/lvalues and references
27
bool makeEven (int& x) {// make number even and return whether or not original number was odd.bool wasOdd = x % 2;x *= 2;return wasOdd;
}
int x = 5;bool wasOdd = f(x);
• lvalues
• anything on the Left side of an equal sign
• an object whose resource can't be reused without consequence
• can't be changed without affecting creator
• lvalues are underlined
• if we change x, its creator (the lines below) will be affected
![Page 28: 8 template functions](https://reader033.fdocuments.in/reader033/viewer/2022041701/62536c0b19184b608f65bd34/html5/thumbnails/28.jpg)
Let's review r-/lvalues and references
28
bool makeEven (int& x) {// make number even and return whether or not original number was odd.bool wasOdd = x % 2;x *= 2;return wasOdd;
}
int x = 5;bool wasOdd = f(x);
• rvalues
• anything on the Right side of an equal sign
• an object whose resource can be reused at no cost to creator
• rvalues are underlined
• if we change 2, nothing will be affected.
![Page 29: 8 template functions](https://reader033.fdocuments.in/reader033/viewer/2022041701/62536c0b19184b608f65bd34/html5/thumbnails/29.jpg)
Let's review r-/lvalues and references
29
• lvalue references - any reference to an lvalue (&)
• rvalue references - any reference to an rvalue (&&) (will be explained in our move semantics lecture)
• Pointers are objects that store a reference
int x = 5;&x // lvalue referenceint* pointer = &x
![Page 30: 8 template functions](https://reader033.fdocuments.in/reader033/viewer/2022041701/62536c0b19184b608f65bd34/html5/thumbnails/30.jpg)
Template type deduction - case 1
30
• If the template function parameters are regular, pass-by-value parameters:
1. Ignore the "&"
2. After ignoring "&", ignore const too.
template <typename Type>Type addFive(Type a) {return a + 5; // only works for types that support "+"
}
int a = 5; addFive(a); // Type is intconst int b = a;addFive(b); // Type is still intconst int& c = a;addFive(c); // even now, Type is still int
![Page 31: 8 template functions](https://reader033.fdocuments.in/reader033/viewer/2022041701/62536c0b19184b608f65bd34/html5/thumbnails/31.jpg)
Template type deduction - case 2
31
template <typename Type>void makeMin(const Type& a, const Type& b, Type& minObj) {
// set minObj to the min of a and b instead of returning.minObj = a < b ? a : b;
}
const int a = 20; const int& b = 21; int c; myMin(a, b, c); // Type is deduced to be intcout << c << endl; // 20
a and b are references to const values
• If the template function parameters are references or pointers, this is how types (e.g. Type) are deduced:
1. Ignore the "&"
2. Match the type of parameters to inputted arguments
3. Add on const after
![Page 32: 8 template functions](https://reader033.fdocuments.in/reader033/viewer/2022041701/62536c0b19184b608f65bd34/html5/thumbnails/32.jpg)
32
Template Functions DemoTemplate Functions: syntax and initialization
![Page 33: 8 template functions](https://reader033.fdocuments.in/reader033/viewer/2022041701/62536c0b19184b608f65bd34/html5/thumbnails/33.jpg)
Template Functions (behind the scenes)
33
• Normal functions are created during compile time, and used in runtime.
• Template functions are not compiled until used by the code.
• The compiler deduces the parameter types and generates a unique function specifically for each time the template function is called.
• After compilation, the compiled code looks as if you had written each instantiated version of the function yourself.
template <typename Type>Type myMin(Type a, Type b) {return a < b ? a : b;
}cout << myMin(3, 4) << endl; // 3
![Page 34: 8 template functions](https://reader033.fdocuments.in/reader033/viewer/2022041701/62536c0b19184b608f65bd34/html5/thumbnails/34.jpg)
Template Functions (behind the scenes)
34
• To recap instantiation, when you call a template function, either:
• for explicit instantiation, compiler creates a function in the executable that matches the initial function call's template type parameters
• for implicit instation, the compiler does the same,
![Page 35: 8 template functions](https://reader033.fdocuments.in/reader033/viewer/2022041701/62536c0b19184b608f65bd34/html5/thumbnails/35.jpg)
35
What other types of code can we run during compilation?
![Page 36: 8 template functions](https://reader033.fdocuments.in/reader033/viewer/2022041701/62536c0b19184b608f65bd34/html5/thumbnails/36.jpg)
36
Template MetaprogrammingWriting code that runs during compilation (instead of run time)
![Page 37: 8 template functions](https://reader033.fdocuments.in/reader033/viewer/2022041701/62536c0b19184b608f65bd34/html5/thumbnails/37.jpg)
What is TMP?
37
• Normal code runs during run time.
• TMP -> run code during compile time
• make compiled code packages smaller
• speed up code when it's actually running
![Page 38: 8 template functions](https://reader033.fdocuments.in/reader033/viewer/2022041701/62536c0b19184b608f65bd34/html5/thumbnails/38.jpg)
What is TMP?
38
• Normal code runs during run time.
• TMP -> run code during compile time
• make compiled code packages smaller
• speed up code when it's actually running
template<unsigned n>struct Factorial {
enum { value = n * Factorial<n - 1>::value };};
template<> // template class "specialization"struct Factorial<0> {
enum { value = 1 };};
std::cout << Factorial<10>::value << endl; // prints 3628800, but run during compile time!
![Page 39: 8 template functions](https://reader033.fdocuments.in/reader033/viewer/2022041701/62536c0b19184b608f65bd34/html5/thumbnails/39.jpg)
How can TMP actually be used?
39
• TMP was actually discovered (not invented, discovered) recently!
• Where can TMP be applied?
• Ensuring dimensional unit correctness
• Optimizing matrix operations
• Generating custom design pattern implementation
• policy-based design (templates generating their own templates)
![Page 40: 8 template functions](https://reader033.fdocuments.in/reader033/viewer/2022041701/62536c0b19184b608f65bd34/html5/thumbnails/40.jpg)
40
Let's get some practice with making template functions by solving a problem you may see in the future!
Why write generic functions?
![Page 41: 8 template functions](https://reader033.fdocuments.in/reader033/viewer/2022041701/62536c0b19184b608f65bd34/html5/thumbnails/41.jpg)
41
Why write generic functions?Count the # of times 3 appears in a std::vector<int>. Count the # of times "Y" appears in a std::istream. Count the # of times 5 appears in the second half of a std::deque<int>. Count the # of times "X" appear in the second half of a std::string.
![Page 42: 8 template functions](https://reader033.fdocuments.in/reader033/viewer/2022041701/62536c0b19184b608f65bd34/html5/thumbnails/42.jpg)
42
Why write generic functions?
By using generic functions, we can solve each of these problems with a single function!
Count the # of times 3 appears in a std::vector<int>. Count the # of times "Y" appears in a std::istream. Count the # of times 5 appears in the second half of a std::deque<int>. Count the # of times "X" appear in the second half of a std::string.
![Page 43: 8 template functions](https://reader033.fdocuments.in/reader033/viewer/2022041701/62536c0b19184b608f65bd34/html5/thumbnails/43.jpg)
43
Counting Occurrences: Attempt 1int count_occurrences(std::vector<std::string> vec, std::string target){ int count = 0; for (size_t i = 0; i < vec.size(); ++i){ if (vec[i] == target) count++; } return count;}
Usage: count_occurrences({"Xadia", "Drakewood", "Innean"}, "Xadia");
![Page 44: 8 template functions](https://reader033.fdocuments.in/reader033/viewer/2022041701/62536c0b19184b608f65bd34/html5/thumbnails/44.jpg)
44
Counting Occurrences: Attempt 1
🤔 What if we wanted to generalize this beyond just strings?
int count_occurrences(std::vector<std::string> vec, std::string target){ int count = 0; for (size_t i = 0; i < vec.size(); ++i){ if (vec[i] == target) count++; } return count;}
Usage: count_occurrences({"Xadia", "Drakewood", "Innean"}, "Xadia");
![Page 45: 8 template functions](https://reader033.fdocuments.in/reader033/viewer/2022041701/62536c0b19184b608f65bd34/html5/thumbnails/45.jpg)
45
Counting Occurrences: Attempt 2template <typename DataType>int count_occurrences(const std::vector<DataType> vec, DataType target){ int count = 0; for (size_t i = 0; i < vec.size(); ++i){ if (vec[i] == target) count++; } return count;}
Usage: count_occurrences({"Xadia", "Drakewood", "Innean"}, "Xadia");
![Page 46: 8 template functions](https://reader033.fdocuments.in/reader033/viewer/2022041701/62536c0b19184b608f65bd34/html5/thumbnails/46.jpg)
46
Counting Occurrences: Attempt 2template <typename DataType>int count_occurrences(const std::vector<DataType> vec, DataType target){ int count = 0; for (size_t i = 0; i < vec.size(); ++i){ if (vec[i] == target) count++; } return count;}
Usage: count_occurrences({"Xadia", "Drakewood", "Innean"}, "Xadia");
🤔 What if we wanted to generalize this beyond just vectors?
![Page 47: 8 template functions](https://reader033.fdocuments.in/reader033/viewer/2022041701/62536c0b19184b608f65bd34/html5/thumbnails/47.jpg)
47
Counting Occurrences: Attempt 3template <typename Collection, typename DataType>int count_occurrences(const Collection& arr, DataType target){ int count = 0; for (size_t i = 0; i < arr.size(); ++i){ if (arr[i] == target) count++; } return count;}
Usage: count_occurrences({"Xadia", "Drakewood", "Innean"}, "Xadia");
🤔 What's wrong with this? Exactly! The collection may not be indexable. How do we solve this?
![Page 48: 8 template functions](https://reader033.fdocuments.in/reader033/viewer/2022041701/62536c0b19184b608f65bd34/html5/thumbnails/48.jpg)
48
Counting Occurrences: Attempt 4template <typename InputIt, typename DataType>int count_occurrences(InputIt begin, InputIt end, DataType target){ int count = 0; for (initialization; end-condition; increment){ if (element access == target) count++; } return count;}
vector<std::string> lands = {"Xadia", "Drakewood", "Innean"};Usage: count_occurrences(arg1, arg2, "Xadia");
![Page 49: 8 template functions](https://reader033.fdocuments.in/reader033/viewer/2022041701/62536c0b19184b608f65bd34/html5/thumbnails/49.jpg)
49
Counting Occurrences: Attempt 4template <typename InputIt, typename DataType>int count_occurrences(InputIt begin, InputIt end, DataType target){ int count = 0; for (auto iter = begin; iter != end; ++iter){ if (*iter == target) count++; } return count;}
vector<std::string> lands = {"Xadia", "Drakewood", "Innean"};Usage: count_occurrences(lands.begin(), lands.end(), "Xadia");
Nice work! We manually pass in begin and end so that we can customize our search bounds.
![Page 50: 8 template functions](https://reader033.fdocuments.in/reader033/viewer/2022041701/62536c0b19184b608f65bd34/html5/thumbnails/50.jpg)
50
count_occurrences demoTemplate Functions: syntax and initialization
![Page 51: 8 template functions](https://reader033.fdocuments.in/reader033/viewer/2022041701/62536c0b19184b608f65bd34/html5/thumbnails/51.jpg)
51
Are we done?template <typename InputIt, typename DataType>int count_occurrences(InputIt begin, InputIt end, DataType val) { int count = 0; for (auto iter = begin; iter != end; ++iter) { if (*iter == val) count++; } return count;}
Usage: std::string str = "Xadia";Usage: count_occurrences(str.begin(), str.end(), 'a');
Could we reuse this to find how many vowels are in ”Xadia”, or how many odd numbers were in a std::vector<int>?
![Page 52: 8 template functions](https://reader033.fdocuments.in/reader033/viewer/2022041701/62536c0b19184b608f65bd34/html5/thumbnails/52.jpg)
52
Lambdas and STL AlgorithmsNext lecture!