الفريق العربي للبرمجةأرشيف المنتديات · 2000 – 2023
نسخة أرشيفية للقراءة فقط — التسجيل والمشاركة مغلقان، والمحتوى محفوظ كما كان.

Function Templates درس

بدأه MohammadKaraki في 1 يوليو 2009 · 4 رد · 5,711 مشاهدة · في المواضيع والدروس
مشاركة: واتساب X فيسبوك تيليجرام
#1 صاحب الموضوع

مقدمة

تعتبر القوالب من إحدى أقوى الميزات التي أضيفت للغة السي++ وليست موجودة في السي, وهي باختصار أن تقوم بكتابة كود يتعامل مع أكثر من نوع من البيانات, ويمكن تطبيقها على الدوال والصنوف.

سوف تقدر قوة هذه الميزة عندما تتعامل مع مكتبة القوالب القياسية Standard Template Library والتي تجدها مدعومة في المترجمات الحديثة مثل Visual C++ 6 فما فوق, ومترجم GNU C++.

Function Templates – دوال القوالب (هل أعجبتك الترجمة!! :) )

وهي نوع خاص من الدوال, نطبق عليها مفهوم القوالب, لكي تتعامل معها بعدة أنواع من البيانات, بدون الحاجة لإعادة كتابة دالة خاصة لكل نوع من البيانات,,, سوف تضح الفكرة مع الأمثلة.

الآن,, هذا هو الشكل العام لتعريف دوال القوالب:

template <class identifier> function_declaration;
template <typename identifier> function_declaration;

لا تكترث ,, الفرق الوحيد بين التعريفين هو class و typename , كلاهما يحمل نفس المعنى, ولكن أظن أن وجودهم لمجرد التوافق بين المترجمات.

أنظر لهذا المثال الذي يعيد قيمة الكائن الأكبر:

template<class T>
T   Max(T  first, T second)
{
	return first > second ? first : second;
}

قمنا بإنشاء Template Function مع T كمعامل لهذا القالب, هذا النوع T سيتم تحديده عند التعامل مع هذه الدالة, إلى الآن لم نقم بتحديد نوع البيانات الذي ستتعامل معه هذه الدالة.

الآن, لاستعمال دوال القوالب عليك أن تستدعي هذه الدالة بهذا الشكل:

function_name <type> (parameters);

ولاستدعاء دالتنا Max مع النوع int :

int a, b;
Max<int> (a, b);

الآن ما يقوم به الكمبايلر هو إنشاء نسخة من الدالة Max وتعويض النوع int بدل T, ليتم التعامل معها.

انظر إلى هذا البرنامج, لكي تتضح الفكرة أكثر:

#include <iostream>

using namespace std;

T   Max(T  first, T second)
{
			   return first > second ? first : second;
}

int main() {
	int integer1 = 5, integer2 = 10, integer3;
	double real1 = 7.5, real2 = 3.991, real3;
	integer3 = Max<int> (integer1, integer2);
	real3 = Max<double> (real1, real2);
	cout << "Max integer is: " << integer3 << endl;
	cout << "Max double is: " << real3 << endl;
	return 0;
}

في هذا الكود, يقوم الكمبايلر بإنتاج نسختين من الـدالة Max واحدة يعوض فيها int والأخرى double,

طبعا في هكذا كود, يقوم الكمبايلر بتقديم خدمة جليلة للمبرمج, وهي كالتالي

integer3 = Max(integer1, integer2);

فبما أننا مررنا معاملات من النوع int, فبشكل تلقائي سيعتبر الكمبايلر أن المعامل T هو من النوع int, دون الحاجة إلى كتابة <int> بعد اسم الدالة.

في النهاية أحب أن أذكر أنه بإمكانك تمرير أكثر معامل لتكوين القالب, مثلا:

template<class T, class B>
T Max(T first, B second)
{
	return first > second ? first : second;
}

والاستخدام سيكون كالتالي:

float a = 5.0f;
double b = 52.3;
x = Max<float, double> (a, b);

هذا والله أعلم, سأحاول إعداد شرح خاص بقوالب الصنوف, ما رأيكم؟؟..

تحياتي

تم تعديل هذه المشاركة بواسطة MoHammaD_93 في 1 يوليو 2009 في 22:47

1

SAFETY TIP : Always delete what you new, and free what you malloc, never mix new with free or malloc with delete.

#2

بارك الله فيك , درس منظم و واضح , تم اضافة الدرس لكتاب المنتدى بعد اذن الاخوة مشرفي القسم .

اقتباس
فبما أننا مررنا معاملات من النوع int, فبشكل تلقائي سيعتبر الكمبايلر أن المعامل T هو من النوع int, دون الحاجة إلى كتابة <int> بعد اسم الدالة.

اهمم .. كان لدي التباس حول دالة في Boost شكلها كذا :

template<typename Target, typename Source>
  inline
  Target numeric_cast ( Source arg )
  {
	typedef boost::numeric::converter<Target,Source> Converter;
	return Converter::convert(arg);
  }


وعند استدعائها , نقوم بالتالي :

	 short _shot =100;
	 long  _long = 300;

	_short =boost::numeric_cast<short>(_long);

نقطة الالتباس لدي , لماذا عيّنا نوع واحد فقط , ولم نعيّن كلا النوعين المطلوبين target - source , في الاخير , عرفت أنه يجب تعيين نوع return value ولكن لايجب تعيين نوع البارمترات ,

اقتباس
هذا والله أعلم, سأحاول إعداد شرح خاص بقوالب الصنوف, ما رأيكم؟؟..

ممتاز , اذا كان الشرح بسيط ومنظم كهذا :D

والأفضل هو التطرّق لمواضيع جديدة مثل :

1- Nontype Function/Class Template

2- Zero Initialization

3- Specialization and Overloading

,هناك مواضيع كثيرة , يمكن الاطلاع عليها من كتاب

C++ Templates : the Complete Guide

تم تعديل هذه المشاركة بواسطة الشمري في 2 يوليو 2009 في 16:39

logo1.png تطبيق طمأنينة ، نسخة بيتا على أندرويد

عبدالله الشمّري - Al-Shammari

CodingAlone.com

twitter @abshammeri

abshammeri AT gmail.com

github : abshammeri

#3

السلام عليكم ...

مقدمة جميلة أخي محمد :)

اقتباس
نقطة الالتباس لدي , لماذا عيّنا نوع واحد فقط , ولم نعيّن كلا النوعين المطلوبين target - source , في الاخير , عرفت أنه يجب تعيين نوع return value ولكن لايجب تعيين نوع البارمترات ,

لأنه لا توجد طريقة لمعرفة نوع الـ target :)

أما الـ source فإنه يتم معرفة النوع بمجرد كونه argument..

تحياتي ...

#4

مشكورين عالمرور اخواني,,,

اقتباس
والأفضل هو التطرّق لمواضيع جديدة مثل :

سأحاول إن شاء الله,, تحياتي

SAFETY TIP : Always delete what you new, and free what you malloc, never mix new with free or malloc with delete.

مواضيع مشابهة