C++ Templates

در C++، Template (قالب) یک قابلیت قدرتمنده که اجازه می‌ده توابع یا کلاس‌های کلی (Generic) بنویسیم؛ یعنی بدون مشخص کردن نوع دقیق داده، یک بار کد می‌نویسیم و بعد برای انواع مختلف استفاده می‌کنیم.

🔹 چرا Template؟

فرض کنید می‌خواهیم تابعی بنویسیم که دو عدد رو جابه‌جا (swap) کنه.
اگه نوع داده فرق کنه (int، double، string و …) مجبوریم برای هر کدوم یک تابع جدا بنویسیم.
با Template فقط یک بار می‌نویسیم.

1️⃣ Function Template

ساختار کلی

template <typename T> T functionName(T a, T b) { // کد }
  • template شروع تعریفه.

  • typename یا class برای تعیین پارامتر نوع (هر دو یکی هستن).

  • T نام نوع عمومی (می‌تونه هر اسمی باشه).

مثال: تابع swap

#include <iostream> using namespace std; template <typename T> void mySwap(T &x, T &y) { T temp = x; x = y; y = temp; } int main() { int a = 10, b = 20; mySwap(a, b); cout << a << " " << b << endl; // خروجی: 20 10 double c = 1.5, d = 2.5; mySwap(c, d); cout << c << " " << d << endl; // خروجی: 2.5 1.5 return 0; }

2️⃣ Class Template

ساختار کلی

template <class T> class ClassName { T data; public: ClassName(T d) : data(d) {} void show() { cout << data << endl; } };

مثال:

#include <iostream> using namespace std; template <typename T> class Box { T value; public: Box(T v) : value(v) {} void display() { cout << value << endl; } }; int main() { Box<int> intBox(42); intBox.display(); // خروجی: 42 Box<string> strBox("Hello Templates"); strBox.display(); // خروجی: Hello Templates return 0; }

3️⃣ Template با چند پارامتر

می‌تونیم چند نوع مختلف بگیریم:

template <typename T1, typename T2> void printPair(T1 a, T2 b) { cout << a << " - " << b << endl; } int main() { printPair(10, "apple"); printPair(3.14, 42); return 0; }

4️⃣ Default Type برای Template

میشه نوع پیش‌فرض تعیین کرد:

template <typename T = int> class Number { T x; public: Number(T v = 0) : x(v) {} void show() { cout << x << endl; } }; int main() { Number<> n1; // پیش‌فرض int n1.show(); // خروجی: 0 Number<double> n2(3.5); n2.show(); // خروجی: 3.5 }

5️⃣ Template Specialization (ویژه‌سازی)

برای یک نوع خاص می‌تونیم پیاده‌سازی متفاوت بدیم:

template <typename T> class Printer { public: void print(T v) { cout << v << endl; } }; // ویژه‌سازی برای bool template <> class Printer<bool> { public: void print(bool v) { cout << (v ? "TRUE" : "FALSE") << endl; } }; int main() { Printer<int> p1; p1.print(100); // خروجی: 100 Printer<bool> p2; p2.print(true); // خروجی: TRUE }

نکات مهم

  • Templates در زمان کامپایل گسترش پیدا می‌کنن (Compile-time).

  • خطاهای نوع (Type errors) هم در زمان کامپایل مشخص میشن.

  • برای توابع، اگر نوع آرگومان‌ها مشخص باشه، کامپایلر خودش نوع T رو حدس می‌زنه.

  • امکان استفاده‌ی تو در تو (Nested Templates) هم هست.

💡 خلاصه:
Templates ابزار «کد عمومی» در C++ هستن: یک بار بنویس، برای هر نوعی استفاده کن—از توابع ساده تا کلاس‌های پیچیدهٔ کتابخانه استاندارد (STL) همگی بر پایهٔ Template ساخته شدن.