variadic templateها با طعم کیوت

به نام خدا

سلام دوستان امیدوارم حالتون خوب باشه.

حتما میدونید که یکی از ویژگی های جذاب! در C++11 وجود Variadic Template ها هستند. حالا اصلا این که میگی یعنی چی؟ بذارید با یه مثال توضیح بدم. حتما تا الان از تابع printf زیاد استفاده کردید. هیچ وقت شده از خودتون بپرسید چرا این تابع اینقدر انعطاف پذیره و می‌تونه تعداد متغیری پارامتر رو پذیره. یعنی شما می‌تونید یه پارامتر بهش بدید یا دوتا یا سه تا یا چهار تا یا پنج تا یا شیش تا… اهان بسه دیگه!

جالب بدونید که این مثالی که زدم هیچ ربطی به Variadic Template ها نداره! اصن printf رو چه به C++11! ولی یه جورایی ربط داره. توی C++11 شما اگه بخواهید یه تابع بنویسید که هرچه قدر دلتون خواست پارامتر با typeهای مختلف بگیره باید برید سراغ variadic template ها.

خب بذارید با یه مثال بفهمیم چین این variadic template ها. چین نه ها چین. خب دیگه حتما از تابع QString::arg استفاده کردید دیگه. واسه این که داخل یه متن مثلا یه عددی رو جاسازی کنید می‌تونید از این تابع استفاده کنید. مثلا فرض کنید یه تابع قراره سن یه فرد رو بگیره و بعد یه رشته برگردونه بگه سن شما n سال بود و به جای n سن طرف رو بذاره:

خب قراره از این چطوری برسیم به variadic template ها ؟ توابع logging رو دیدید؟ توابعی که برای ایجاد لاگ استفاده می‌شه؟ شما وقتی قراره یه چیزی رو لاگ کنید یه رخدادی رو لاگ کنید معمولا ممکنه بخواهید یه پیامی رو لاگ کنید که حاوی چندین رشته و عدد و ایناست. ممکنه یه بار یه چیزی رو بخواهید لاگ کنید که حاوی دو رشته و سه عدده. یه بار دیگه حاوی یه رشته و چهار عدد صحیح و دو عدد اعشار… خلاصه اگه یه تابع خوبی بود هرچی ما بهش میگفتیم رو میگرفت با یه فرمتی تبدیل به رشته می‌کرد و چاپش میکرد بد نبود. مثلا رشته زیر رو ببنید. ( همه این کارهایی که میخواهیم با variadic template ها بکنیم خب طبیعیه با یه سری + و تابع دیگه قابل انجامه)

ولی ما قصد داریم با variadic templateها یکم خوشگل تر این کار رو بکنیم.

یه مثال ساده

نحوه نوشتن یه تابع variadic به صورت زیره:

برای تعریف یه تابع به صورتی که تعداد دلخواهی پارامتر بگیره باید به صورت بالا دو تابع template ای تعریف کرد. در مثال بالا typename... Args با نام template parameter pack, و Args... args با نام function parameter pack شناخته میشه. در مثال بالا تابع adder میتونه هرچقدر متغیر که تابع جمع + براش تعریف شده رو به عنوان پارامتر بگیره. نکته جالب اینه که در نوشتن variadic template ها دقیقا باید مثل توابع recursive رفتار کرد. یعنی یه شرط خاتمه و یک سری صدا زدنهای بازگشتی تابع. در کد بالا هم می‌بینید که تابع اول در واقع باعث خاتمه تابع می‌شه و تابع دوم بخش تکراری کار هستش. خب بذارید یه مثال ببینیم شاید بهتر جا بیفته. فرض کنید تابع بالا رو به صورت

صدا زدید. این فراخوانی باعث فراخوانی adder به صورتهای زیر می‌شه:

یعنی انگار ۱ واسه پارامتر اول پاس داده میشه و ۲و۳و۸و۷ واسه پارامتر دوم یا همون function parameter pack. بعدخب به صورت بازگشتی این باعث میشه که تابع adder باز صدا زده بشه و این بار ۲ به عنوان پارامتر اول و ۳و۸و۷ به عنوان پارامتر دوم ارسال شن. این کار انقدر ادامه پیدا می‌کنه تا تابع اول adder با مقدار ۷ صدا زده بشه…جه چالب!

تابع Logger با طعم کیوت

خب حالا بیایید همین مفهوم رو توی کیوت و با تابع arg انجام بدیم…

خب من توی تابع اصلی ام میام و سریع پارامتر اول رو قالب میکنم توی یه رشته‌ای(تا عدد بودن یا رشته بودنش برام مهم نباشه) بعد میچسبونمش به فراخوانی بعدی تابع و بازگردانیش میکنم. که این باز به صورت بازگشتی باعث صدا شدن تابع prepare_to_log میشه تا این که در نهایت هیچ پارامتری باقی نمیمونه و تابع اول صدا زده میشه و یه رشته خالی برمیگردونه.

اینم دوتا مثال از فراخونی این تابع:

امیدوارم از این قسمت از برنامه ها خوشتون اومده باشه.

۱۵,۰۸۰ total views, 123 views today

Print Friendly, PDF & Email

درباره ی سعید دادخواه

یه برنامه نویس !

همچنین ببینید

ریزه میزه – دسترسی به عناصر یک tuple

سلام دوستان گل. من سعی میکنم با توجه به وقت کم من و شما مطالب …

3
دیدگاه بگذارید

avatar
3 Comment threads
0 Thread replies
0 دنبال کنندگان
 
Most reacted comment
داغ ترین نخ نظرات
3 کامنت گذاران
m.coderstackprogramerمهران کامنت گذاران اخیر
  مشترک شو!  
جدیدترین قدیمی‌ترین دارای بیشترین امتیاز
میخوام باخبر شم از
مهران
Guest
مهران

مثل همیشه عالی …. منتظر پست های جددتون هستیم

stackprogramer
Guest

بسیار مفید بود. تشکر

m.coder
Member
m.coder

خیلی هم عالی 👍