Professional C__ - Marc Gregoire [343]
The auto keyword here instructs the compiler that the prototype is using the alternative function syntax, which is a completely different meaning than the auto keyword that is introduced in Chapter 1 to let the compiler automatically deduce the type of an expression.
FUNCTION TEMPLATES
You can also write templates for stand-alone functions. For example, you could write a generic function to find a value in an array and return its index:
static const size_t NOT_FOUND = (size_t)(-1);
template size_t Find(T& value, T* arr, size_t size) { for (size_t i = 0; i < size; i++) { if (arr[i] == value) { return i; // Found it; return the index } } return NOT_FOUND; // Failed to find it; return NOT_FOUND } Code snippet from FunctionTemplate\FindTemplate.cpp The Find() function template can work on arrays of any type. For example, you could use it to find the index of an int in an array of ints or a SpreadsheetCell in an array of SpreadsheetCells. You can call the function in two ways: explicitly specifying the type with angle brackets or omitting the type and letting the compiler deduce it from the arguments. Here are some examples: int x = 3, intArr[] = {1, 2, 3, 4}; size_t sizeIntArr = sizeof(intArr) / sizeof(int); size_t res; res = Find(x, intArr, sizeIntArr); // calls Find res = Find if (res != NOT_FOUND) cout << res << endl; else cout << "Not found" << endl; double d1 = 5.6, dArr[] = {1.2, 3.4, 5.7, 7.5}; size_t sizeDoubleArr = sizeof(dArr) / sizeof(double); res = Find(d1, dArr, sizeDoubleArr); // calls Find res = Find if (res != NOT_FOUND) cout << res << endl; else cout << "Not found" << endl; //res = Find(x, dArr, sizeDoubleArr); // DOES NOT COMPILE! // Arguments are different types. SpreadsheetCell c1(10), c2Arr[2] = {SpreadsheetCell(4), SpreadsheetCell(10)}; size_t sizeC2Arr = sizeof(c2Arr) / sizeof(SpreadsheetCell); res = Find(c1, c2Arr, sizeC2Arr); res = Find Code snippet from FunctionTemplate\FindTemplate.cpp Like class templates, function templates can take non-type parameters. For brevity, only an example of a type parameter for function templates is shown. The C++ standard library provides a templatized find() function that is much more powerful than the one above. See Chapter 13 for details. Function Template Specialization Just as you can specialize class templates, you can specialize function templates. For example, you might want to write a Find() function for char* C-style strings that compares them with strcmp() instead of operator==. Here is a specialization of the Find() function to do this: template<> size_t Find { cout << "Specialization" << endl; for (size_t i = 0; i < size; i++) { if (strcmp(arr[i], value) == 0) { return i; // Found it; return the index } } return NOT_FOUND; // Failed to find it; return NOT_FOUND } Code snippet from FunctionTemplate\FindTemplateSpecialization.cpp You can omit the template<> size_t Find(char*& value, char** arr, size_t size) However, the deduction rules are tricky when you involve overloading as well (see next section), so, in order to avoid mistakes, it’s better to note the type explicitly. Although the specialized find() function could take just char* instead of char*& as its first parameter, it’s best to keep the arguments parallel to the non-specialized version of the function for the deduction rules to function properly. You can use the specialization as follows: char* word = "two"; char* arr[] = {"one", "two", "three", "four"}; size_t sizeArr = sizeof(arr) / sizeof(arr[0]); size_t res; res = Find res = Find(word, arr, sizeArr); // Calls