Giao diện
Template Basics
🎯 Mục tiêu
🎯 Sau bài thực hành này, bạn sẽ:
- Viết function templates generic cho nhiều kiểu dữ liệu
- Tạo class templates có thể tái sử dụng
- Áp dụng template specialization cho trường hợp đặc biệt
- Sử dụng type traits để kiểm tra kiểu tại compile-time
Mô tả bài tập
Templates cho phép viết code generic — một lần viết, nhiều kiểu dùng. Đây là nền tảng của STL.
Yêu cầu
Bài 1: Function Templates
Viết maxOf và printArray template.
cpp
template <typename T>
T maxOf(T a, T b) { /* TODO: trả về giá trị lớn hơn */ }
template <typename T, size_t N>
void printArray(const T (&arr)[N]) { /* TODO: in mảng, phân tách ", " */ }
int main() {
std::cout << maxOf(3, 7) << std::endl; // 7
std::cout << maxOf(3.14, 2.71) << std::endl; // 3.14
int nums[] = {1, 2, 3, 4, 5};
printArray(nums); // 1, 2, 3, 4, 5
}1
2
3
4
5
6
7
8
9
10
11
12
2
3
4
5
6
7
8
9
10
11
12
Bài 2: Class Template — Stack
cpp
template <typename T>
class Stack {
std::vector<T> data;
public:
void push(const T& value); // thêm phần tử
T pop(); // xóa và trả về đỉnh, throw nếu rỗng
const T& top() const; // xem đỉnh
bool empty() const;
size_t size() const;
};1
2
3
4
5
6
7
8
9
10
2
3
4
5
6
7
8
9
10
Bài 3: Template Specialization & Type Traits
cpp
template <typename T>
std::string format(const T& value) { return std::to_string(value); }
// TODO: Specialization cho std::string (trả về trực tiếp)
// TODO: Specialization cho bool (trả về "true"/"false")
template <typename T>
T safeAdd(T a, T b) {
static_assert(std::is_arithmetic_v<T>, "safeAdd requires numeric types");
return a + b;
}1
2
3
4
5
6
7
8
9
10
11
2
3
4
5
6
7
8
9
10
11
Gợi ý
Gợi ý Bài 1
maxOf: return (a > b) ? a : b;. printArray: template nhận size N, dùng vòng lặp đến N.
Gợi ý Bài 2
pop(): kiểm tra data.empty(), lưu data.back(), gọi data.pop_back(), return.
Lời giải tham khảo
Xem lời giải
cpp
template <typename T>
T maxOf(T a, T b) { return (a > b) ? a : b; }
template <typename T, size_t N>
void printArray(const T (&arr)[N]) {
for (size_t i = 0; i < N; ++i) {
if (i > 0) std::cout << ", ";
std::cout << arr[i];
}
std::cout << std::endl;
}
template <typename T>
void Stack<T>::push(const T& value) { data.push_back(value); }
template <typename T>
T Stack<T>::pop() {
if (data.empty()) throw std::runtime_error("Stack is empty");
T val = data.back(); data.pop_back(); return val;
}
template <typename T>
const T& Stack<T>::top() const {
if (data.empty()) throw std::runtime_error("Stack is empty");
return data.back();
}
template <> std::string format<std::string>(const std::string& v) { return v; }
template <> std::string format<bool>(const bool& v) { return v ? "true" : "false"; }1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
📚 Bài liên quan