C++ Templates - A Professional Guide
1. Templates
Q: What are templates in C++?
Templates are a C++ feature that enables generic programming by allowing functions and classes to operate on different data types without rewriting code. They are defined using the template keyword and are widely used in DSA for reusable data structures (e.g., generic stacks, queues) and algorithms (e.g., sorting).
Q: What are the types of templates in C++?
- Function Templates: Generic functions that work with any data type.
- Class Templates: Generic classes for creating type-independent data structures.
- Variable Templates (C++14): Templates for variables.
- Alias Templates (C++11): Type aliases for templates.
Q: How do you declare a function template?
Use the template keyword followed by a type parameter (typically typename or class) and define the function.
Syntax:
template <typename T>
return_type function_name(T param1, T param2) {
// Function body
}
Q: How do you declare a class template?
Use the template keyword followed by a type parameter and define the class.
Syntax:
template <typename T>
class ClassName {
// Members and methods
};
Q: Can you give an example of a function template in C++?
#include <iostream>
using namespace std;
// Function template to find maximum
template <typename T>
T maximum(T a, T b) {
return (a > b) ? a : b;
}
int main() {
// Works with int
cout << "Max of 5, 10: " << maximum(5, 10) << endl; // Output: 10
// Works with double
cout << "Max of 3.14, 2.71: " << maximum(3.14, 2.71) << endl; // Output: 3.14
// Works with char
cout << "Max of 'a', 'z': " << maximum('a', 'z') << endl; // Output: z
return 0;
}
Output:
Max of 5, 10: 10
Max of 3.14, 2.71: 3.14
Max of 'a', 'z': z
Q: Can you give an example of a class template in C++?
#include <iostream>
using namespace std;
template <typename T>
class Pair {
private:
T first, second;
public:
Pair(T f, T s) : first(f), second(s) {}
T getFirst() const { return first; }
T getSecond() const { return second; }
void display() const {
cout << "Pair: (" << first << ", " << second << ")" << endl;
}
};
int main() {
// Pair of integers
Pair<int> intPair(1, 2);
intPair.display(); // Output: Pair: (1, 2)
// Pair of doubles
Pair<double> doublePair(3.14, 2.71);
doublePair.display(); // Output: Pair: (3.14, 2.71)
// Pair of strings
Pair<string> stringPair("hello", "world");
stringPair.display(); // Output: Pair: (hello, world)
return 0;
}
Output:
Pair: (1, 2)
Pair: (3.14, 2.71)
Pair: (hello, world)
Q: How are templates used in DSA?
- Generic Data Structures: Implement reusable structures like stacks, queues, or linked lists that work with any data type (e.g.,
std::vector<T>). - Generic Algorithms: Write type-independent algorithms like sorting or searching (e.g.,
std::sortin STL). - Efficiency: Templates generate type-specific code at compile-time, avoiding runtime overhead.
Q: Can you give a DSA-related example using templates?
Example: A generic stack class template.
#include <iostream>
using namespace std;
template <typename T>
class Stack {
private:
static const int MAX = 100;
T arr[MAX];
int top;
public:
Stack() : top(-1) {}
void push(T value) {
if (top >= MAX - 1) {
cout << "Stack Overflow" << endl;
return;
}
arr[++top] = value;
}
T pop() {
if (top < 0) {
cout << "Stack Underflow" << endl;
return T(); // Return default value
}
return arr[top--];
}
bool isEmpty() const {
return top < 0;
}
};
int main() {
// Stack of integers
Stack<int> intStack;
intStack.push(1);
intStack.push(2);
intStack.push(3);
cout << "Int Stack Pop: " << intStack.pop() << endl; // 3
cout << "Int Stack Pop: " << intStack.pop() << endl; // 2
// Stack of doubles
Stack<double> doubleStack;
doubleStack.push(3.14);
doubleStack.push(2.71);
cout << "Double Stack Pop: " << doubleStack.pop() << endl; // 2.71
// Stack of strings
Stack<string> stringStack;
stringStack.push("hello");
stringStack.push("world");
cout << "String Stack Pop: " << stringStack.pop() << endl; // world
return 0;
}
Output:
Int Stack Pop: 3
Int Stack Pop: 2
Double Stack Pop: 2.71
String Stack Pop: world
Q: What is template specialization?
Template specialization provides a specific implementation for a particular type, overriding the generic template.
Example:
#include <iostream>
#include <string>
using namespace std;
template <typename T>
class Printer {
public:
void print(T value) {
cout << "Generic: " << value << endl;
}
};
// Specialization for string
template <>
class Printer<string> {
public:
void print(string value) {
cout << "String: " << value << " (length: " << value.length() << ")" << endl;
}
};
int main() {
Printer<int> intPrinter;
intPrinter.print(42); // Output: Generic: 42
Printer<string> stringPrinter;
stringPrinter.print("Hello"); // Output: String: Hello (length: 5)
return 0;
}
Output:
Generic: 42
String: Hello (length: 5)
Q: How do templates differ from C?
- C++: Supports templates for generic programming, enabling type-safe, reusable code.
- C: Lacks templates; generic behavior requires macros or
void*pointers, which are error-prone and less type-safe. - C++ Advantage: Templates power STL (e.g.,
std::vector,std::map), simplifying DSA implementations.
Q: What are common mistakes with templates?
- Defining templates in
.cppfiles instead of headers (causes linker errors). - Not specifying template parameters explicitly when needed (e.g.,
maximum<int>(5, 10)). - Overcomplicating templates, reducing readability.
- Forgetting to handle edge cases in specializations.
- Ignoring compiler errors due to complex template instantiation.
Q: What are best practices for templates in C++?
- Define templates in header files to avoid linker issues.
- Use
typenameorclassconsistently for clarity. - Provide specializations for specific types when needed.
- Use
constand references in templates to avoid unnecessary copying (e.g.,const T&). - Keep template code simple and well-documented for maintainability.
- Leverage STL templates (e.g.,
std::vector,std::sort) for DSA tasks. - Test templates with multiple types to ensure robustness.
Q: How do templates enhance DSA?
- Reusability: Implement data structures (e.g., stacks, queues) that work with any type.
- Type Safety: Avoid type casting errors common in C's
void*approach. - Performance: Templates generate optimized, type-specific code at compile-time.
- STL: Templates enable STL containers and algorithms, widely used in competitive programming and DSA.