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.