C++ פונקציה עם template, איך אפשר לדעת איזה סוג משתנה נכנס לתבנית? - תכנות - HWzone פורומים
עבור לתוכן
  • צור חשבון

C++ פונקציה עם template, איך אפשר לדעת איזה סוג משתנה נכנס לתבנית?


א

Recommended Posts

למשל פונקציה שמקבלת T ו-G (שניהם משתנים מסוג כלשהו), ומחזירה את הסכום שלהם.

אם G ו-T הם int/double/float/long או כל משתנה אחר שמחזיק מספר, אז זה יהיה מעולה. אבל אם למשל אחד מהם יהיה int והשני string יתקבל דבר בלתי רצוי.

קישור לתוכן
שתף באתרים אחרים

אם אתה רוצה לאפשר לקבל משתנים מסוג מספרי ו-string, אתה יכול כמובן.

השאלה היא מה זה דבר בלתי רצוי? כמובן שהקומפיילר לא יכול לדעת.

יש כמה אופציות:

1. לא להשתמש ב-templates.

2. להשתמש ולבדוק בזמן ריצה האם T הוא String.

3. ליצור פונקציה טמפלטית שתכסה את רוב המקרים ולטפל נקודתית במקרים בעייתיים. תוכל לכתוב פונקציה עם חתימה דומה רק שמקבלת כפרמטר String וטיפוס נוסף טמפלטי.

קישור לתוכן
שתף באתרים אחרים

מה שיקרה פשוט זה שהקוד לא יתקמפל, בדיוק כמו אם תנסה להגדיר int ו-string ואז לחבר ביניהם.

העניין ב-templates הוא כזה: כשאתה מגדיר template, אז לא נוצרת שום מחלקה באמת. המחלקה נוצרת ומתקמפלת רק כשאתה ממש משתמש ב-template. לדוגמה, המחלקה <vector<T היא מחלקה טמפלייטית. כשאתה מגדיר <vector<int אז מה שקורה הוא שהקומפיילר יוצר "עותק" של המחלקה vector, כשהוא מחליף את כל המופעים של T ב-int, ומנסה לקמפל אותו. אותו דבר כשאתה מגדיר <vector<string - הקומפיילר יוצר עותק של המחלקה כשהוא מחליף את T ב-string ומנסה לקמפל. בסופו של דבר אתה מקבל שתי מחלקות נפרדות לחלוטין, כאילו הגדרת מחלקה בשם vector_int ו-vector_string.

בדוגמה שלך, נניח שהגדרת את המחלקה הזו (סלח לי אם הקוד לא מדויק מבחינה תחבירית, הרבה זמן לא כתבתי ++C):


class MyClass<T,G> {
public:
T f(T t, G g) { return t+g; }
}

כשתבוא ליצור משתנה מטיפוס <MyClass<string,int אז הקומפיילר כאמור יחליף את T ב-string ואת G ב-int, וינסה לקמפל את התוצאה. כלומר הוא ינסה לקמפל קוד שנראה ככה:


class MyClass_string_int {
public:
string f(string t, int g) { return t+g; }
}

כיוון שלא קיים אופרטור + בין string ו-int (למיטב זכרוני), הקומפיילר יזרוק שגיאת קומפילציה.

קישור לתוכן
שתף באתרים אחרים

הנה כלל אצבע: templates מתאימים יותר לקונטיינרים ואלגוריתמים סטנדרטיים (sort, swap וכולי). לדברים אחרים ירושה ופולימורפיזם עשוי להתאים יותר.

ממליץ להרחיב בנושא - בגרסאות האחרונות של ++C ישנם פיצ'רים כמו decltype, rtti, static_cast\dynamic_cast

קישור לתוכן
שתף באתרים אחרים

תודה

התכוונתי לפונקציה עם תבנית, ולא למחלקה. למשל בקוד הבא:

template <class T , class G>

void sum(T num1, G num2)
{
cout << "Sum: " << num1 + num2 << endl;

}

יש אפשרות לבדוק בתוך הפונקציה האם T או G הם מחרוזת? (במקום להעמיס פונקציה מיוחדת בנפרד)

קישור לתוכן
שתף באתרים אחרים

אפשרי בעזרת template specialization למשל באופן הבא:


#include <iostream>
#include <string>

using namespace std;

template <typename T1, typename T2>
void print_sum(T1 n1, T2 n2)
{
cout << n1 + n2 << endl;
}

template<>
void print_sum(string s1, string s2)
{
cout << "called print_sum() for a string" << endl;
}

int main()
{
print_sum(3.5, 4);

string s1("Hello ");
string s2("World");
print_sum(s1, s2);
}





קישור לתוכן
שתף באתרים אחרים

כבר הצעתי את זה, אבל טוב שנת קוד כדוגמה.

3. ליצור פונקציה טמפלטית שתכסה את רוב המקרים ולטפל נקודתית במקרים בעייתיים. תוכל לכתוב פונקציה עם חתימה דומה רק שמקבלת כפרמטר String וטיפוס נוסף טמפלטי.

קישור לתוכן
שתף באתרים אחרים

ארכיון

דיון זה הועבר לארכיון ולא ניתן להוסיף בו תגובות חדשות.

×
  • צור חדש...