Ch15: Function Templates¶
TL;DR: Template Blueprints: Function templates act as compiler blueprints. The compiler generates concrete function instances only for the types used in calls (instantiation).
โก Quick Reference¶
#include <iostream>
#include <type_traits>
#include <cstring>
// template <typename T> - Declares a function template with type placeholder T
// T maximum(T a, T b) - Generic function template body
template <typename T>
T maximum(T a, T b) {
return (a > b) ? a : b;
}
// template <> const char* maximum<const char*>(...) - Full specialization for const char*
template <>
const char* maximum<const char*>(const char* a, const char* b) {
return std::strcmp(a, b) > 0 ? a : b;
}
// const T& - Passes parameters by reference to avoid copies
template <typename T>
const T& maximum_ref(const T& a, const T& b) {
return (a > b) ? a : b;
}
// Multiple template parameters with explicit return type
template <typename ReturnType, typename T, typename P>
ReturnType mix_add(T a, P b) {
return a + b;
}
// auto return type & trailing return type with decltype
template <typename T, typename P>
auto mix_add_deduced(T a, P b) -> decltype((a > b) ? a : b) {
return (a > b) ? a : b;
}
// decltype(auto) - Deduces return type preserving references
template <typename T>
decltype(auto) get_ref_value(T& ref) {
return ref;
}
// C++20 abbreviated function template using auto parameters
auto generic_auto(auto a, auto b) {
return a + b;
}
// Non-type template parameter (NTTP)
template <typename T, size_t size>
bool is_valid(T arr[size]) {
return size > 0;
}
int main() {
// static_assert - Performs compile-time validation on template traits
static_assert(std::is_integral_v<int>, "Integer required");
// maximum<T>(a, b) - Explicitly specifies template type argument
auto res = maximum<double>(10, 20.5);
// if constexpr - Executes compile-time branching
if constexpr (sizeof(int) == 4) {
// branch compiled only if true
}
return 0;
}
๐ง Core Concepts¶
- Template Blueprints: Function templates act as compiler blueprints. The compiler generates concrete function instances only for the types used in calls (instantiation).
- Type Deduction & Homogeneity: The compiler automatically deduces template types, but a single template type parameter
Tmust resolve to a single homogeneous type across all arguments. - Specialization & Customization: Full template specialization allows writing custom implementations for specific types (e.g.,
const char*) that bypass the generic blueprint.
โ ๏ธ Pitfalls (Quick Scan)¶
| Mistake | Fix |
|---|---|
| Passing conflicting argument types to a single-parameter template | Provide explicit template arguments like maximum<double>(a, c) |
| Using unsupported operators on template type parameters inside the body | Ensure type parameters support all operators used within the template body |
Comparing const char values using the generic comparison template |
Provide a template specialization using std::strcmp for C-strings |
| Declaring pass-by-value and pass-by-reference overloads of the same template | Stick to one parameter-passing convention, preferably const T& |
Attempting to modify a template parameter passed by const T& |
Avoid modifying parameters declared as const references |
| Implicitly truncating template return types during assignment | Use auto to deduce variables receiving template returns |
| Passing pointers to a template designed to compare values | Dereference pointers at the call site or write a specialization |
| Relying on compilation to catch bugs in unused template parameters | Instantiate templates with all supported types during testing |
๐ Full Details¶
Cause โ Effect โ Fix with timestamp (click to expand)
* **Passing conflicting argument types to a single-parameter template** -> **Compile-time error because compiler cannot resolve type placeholder `T`** -> **Provide explicit template arguments like `maximum๐ Repo Files¶
24.FunctionTemplates/24.2TryingOutFunctionTemplates/main.cpp24.FunctionTemplates/24.3TemplateTypeDeductionAndExplicitArguments/main.cpp24.FunctionTemplates/24.4TemplateTypeParametersByReference/main.cpp24.FunctionTemplates/24.5TemplateSpecialization/main.cpp24.FunctionTemplates/24.6FunctionTemplatesWithOverloading/main.cpp24.FunctionTemplates/24.7FunctionTemplatesWithMultipleParameters/main.cpp24.FunctionTemplates/24.8TemplateReturnTypeDeductionWithAuto/main.cpp24.FunctionTemplates/24.9DecltypeAndTrailingReturnTypes/main.cpp24.FunctionTemplates/24.10DecltypeAuto/main.cpp24.FunctionTemplates/24.11DefaultArguments/main.cpp24.FunctionTemplates/24.12NonTypeTemplateParameters/main.cpp24.FunctionTemplates/24.13AutoFunctionTemplates/main.cpp24.FunctionTemplates/24.14NamedTemplateParametersForLambdas/main.cpp24.FunctionTemplates/24.15TypeTraits/main.cpp24.FunctionTemplates/24.16ConstexprIf/main.cpp