Template nâng cao
1. Function & Class Templates
Function template cho phép viết hàm dùng cho nhiều kiểu dữ liệu:
template
T max(T a, T b) {
return a > b ? a : b;
}
int x = max(3, 5); // T = int
float y = max(2.5f, 1.8f); // T = float
Class template giúp tổng quát hóa định nghĩa lớp:
template
class Box {
T value;
public:
Box(T v) : value(v) {}
T get() const { return value; }
};
Box b1(10);
Box b2("hello");
📌 Nên dùng khi bạn muốn logic hoạt động giống nhau cho nhiều kiểu dữ liệu.
2. Specialization & SFINAE
Template Specialization giúp định nghĩa hành vi riêng biệt cho một kiểu cụ thể:
template
class Printer {
public:
void print(T val) { std::cout << val << "\n"; }
};
// Specialization for bool
template<>
class Printer {
public:
void print(bool val) {
std::cout << (val ? "true" : "false") << "\n";
}
};
SFINAE (Substitution Failure Is Not An Error): cho phép loại bỏ các hàm không phù hợp với điều kiện template tại compile-time:
template
typename std::enable_if::value>::type
print_type(T) {
std::cout << "Integral\n";
}
template
typename std::enable_if::value>::type
print_type(T) {
std::cout << "Floating point\n";
}
⚠️ SFINAE giúp bạn tùy biến hàm mà không cần tạo nhiều overloads tách biệt, cực kỳ hữu ích khi viết thư viện
chung.
3. Type Traits & Concepts (C++20)
Type Traits là meta-programming utilities trong C++ để kiểm tra hoặc sửa đổi kiểu dữ liệu:
#include
std::is_integral::value // true
std::is_floating_point::value // true
Concepts (C++20): Ràng buộc kiểu dữ liệu ở mức compile-time để tăng độ rõ ràng:
template
concept Addable = requires(T a, T b) {
{ a + b } -> std::convertible_to;
};
template
T add(T a, T b) {
return a + b;
}
✅ Concepts thay thế cho SFINAE giúp code rõ ràng hơn, dễ đọc và dễ bảo trì.