The purpose of this quiz is to give you a chance to focus your knowledge of simple cases of making a function into a template in C++.
There are two new keywords for making a generic function pattern that the compiler will fill in when it sees prospective data types in a call to that function. What are they?
TRUE✓ | FALSE✗ | The typename keyword does two jobs in relation to templates. |
---|---|---|
TRUE✓ | FALSE✗ | It introduces a new placeholder name for a data type in the template pattern. |
TRUE✓ | FALSE✗ | It is also used to indicate to the compiler that a nested type
definition/using alias is really a data type
from inside a templated type like so:
typename vector<BaseType>::size_type pos; |
Show a template function to print any vector-based list with caller-specified text before, between, and after the elements.
template <typename BaseType> void display_list(const vector<BaseType> & list, const string & pre_text, const string & between_text, const string & post_text) { cout << pre_text; if ( ! list.empty() ) { for (typename vector<BaseType>::size_type pos = 0; pos+1 != list.size(); ++pos) { cout << list[pos] << between_text; } cout << list.back(); } cout << post_text; return; }
TRUE✓ | FALSE✗ | Sometimes we want to have a particular type behave differently in a templated function than other types. |
---|---|---|
TRUE✓ | FALSE✗ | If it only involves adjusting the code inside the template function, we can specialize the original template to the specially treated type. |
TRUE✓ | FALSE✗ | Overloads of a template function can be templates themselves or can be normal functions. |
Given the following linear search template function, make a new version that locates a string with the same length as a desired target string. Should this new function be a specialization or an overload of the original? Make sure the two functions can coexist in the same code without ambiguity!
template <typename BaseT> inline typename vector<BaseT>::size_type locate(const vector<BaseT> & vec, const BaseT & find_me, typename vector<BaseT>::size_type start = 0) { auto pos{start}; // start at specified position while ( pos < vec.size() && // not at end of vector AND vec[pos] != find_me ) // not found, yet... { ++pos; // try next one... } return pos; // either place findĖme was, or .size() }
If we tried to specialize the above template, we'd end up with an ambiguity of sorts between the functions: template <> inline typename vector<string>::size_type locate(const vector<string> & vec, const string & find_me, typename vector<string>::size_type start = 0) The problem is that we could no longer search for a particular string value within the vector! We'd only be able to search for strings of a certain length. By overloading the template, we can make the string's size a parameter to the function and still be able to search for string values in a vector of strings. Here is the resulting overload: inline typename vector<string>::size_type locate(const vector<string> & vec, string::size_type find_this_length, typename vector<string>::size_type start = 0) { auto pos{start}; while ( pos < vec.size() && vec[pos].length() != find_this_length ) { ++pos; } return pos; } Note that this overload doesn't need to be a template at all.