3 שאלות על tamplate בC++ - תכנות - HWzone פורומים
עבור לתוכן
  • צור חשבון

3 שאלות על tamplate בC++


yogev_23

Recommended Posts

א. אם אני כותב קוד בתוך מחלקה (class), האם מותר לי לקרוא לפונקציות שלה בלי שום הקדמה

כלומר לקרוא למשל

func

ולא

*this.func

ב. אם הגדרתי template<char a>

מיד לפני הגדרת מחלקה, מותר לי ליצור במחלקה פונקציה

char func() {return a;}

אני פשוט לא בטוח כיצד המחלקה מתייחסת למשתנה a (קבוע? char?).. עד היום הגדרתי בtemplate רק מחלקות לא ידועות כמו class SOMETHING ככה שלא עבדתי עם שם ספציפי של משתנה.

ג. לפני מימוש מחלקה כלשהיא, הגדרתי template<class T>

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

template<int> אני רוצה ליצור בתוך המחלקה פונקציה כזאת

String func(){String a = T: return a;}

זה אפשרי? כי זאת פונקציה "דינמית", היא מקבלת תוצאה רק בזמן ריצה. המטרה, אם לא היה ברור, שהמשתנה a יכיל את המחרוזת "int" לדוגמא (כאמור בהתאם למה שהמשתמש בחר להציב ב class T).

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

א. לא רק שמותר, אלא מומלץ. ברוב המקרים אין סיבה להשתמש ב-this.

ב. לא יודע. אני מניח שהוא נחשב קבוע. הדרך הכי טובה לדעת היא לבדוק בעצמך.

ג. אתה יכול להשתמש ב-typeid, בהנחה שהקומפיילר שלך תומך ב-RTTI. בכל מקרה זה לא ממש דבר יפה ולא מומלץ להשתמש בזה.

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

ב. קבוע.

ג. ב-C++ אין reflection. הדבר "הנכון" לעשות במקרה זה זה להשתמש בסוג של traits.


template <typename X>
struct type_name { const char* value = "unknown"; };

template <>
struct type_name<int> { const char* value = "int"; };

template <>
struct type_name<float> { const char* value = "float"; };

...

static template<typename X> inline const char* get_type_string()
{ return type_name<X>::value; }

זה לא אידיאלי, אבל מצד שני כנראה שאפשר למצוא מישהו שעשה את זה בשבילך. נסה boost.

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

ממש התבאסתי מהתשובה ל-ג'..

אגיד לכם מאיפה זה בא ואולי תחכימו אותי עם פתרון מכיוון אחר. אני צריך לממש מחלקה של פולינומים.

לפני הגדרת המחלקה יש template<class T, char c>

כאשר class T זה שדה הפולינום (לדוגמא int, מעל השלמים.. השדה Z), וc זה משתנה הפולינום (מה שבדרך כלל x או t).

הבעיה מתחילה במימוש האופרטורים: נכון מקובל שאופרטורים בינארים סימטריים מגדירים מחוץ למחלקה? למשל האופרטור "+". כשאני מממש את האופרטור הזה מחוץ למחלקה, אני רוצה לוודא לפני ביצוע פעולת החיבור, ששני הארגומנטים הם מאותו class T (אם המימוש היה בתוך המחלקה, לא הייתי צריך לדאוג לזה. אבל יורידו לי נקודות)

על מנת לא ליצור מצב שהאופרטור יקבל שני פולינומים שהוגדרו עם templates שונים. חייבת להיות דרך לכתוב פונקציה שתתן את הערך של T בזמן ריצה, אחרת פולינום מעל החוג Z3 למשל, יתחבר עם פולינום מעל הקומפלקסים.. זה חסר משמעות

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

אבל מה הבעיה בדיוק? הרי אתה לא מגדיר חיבור בין פולינום<Z> לפולינום <R>. אתה תגדיר אופרטור חיבור שבו שני הצדדים הם פולינום מאותו סוג.

כל נסיון לחבר שני פולינומים שאינם מאותו טיפוס יתקל בשגיאת קומפילציה. שזה הרבה יותר טוב משגיאה בזמן ריצה.

זה בדיוק הכוח של static typing + templates - קיבלת פתרון ללא overhead ועם ביטחון שאתה לא יכול לקמפל שגיאה מסוג זה!


template <typename Z> class Poly { ... };

template <typename X> Poly<X> operator+(const Poly<X>& lhs, const Poly<X>& rhs)
{
// Implement Poly<X> addition and return
}

int main()
{
Poly<Z4> z4poly;
Poly <R> rpoly1, rpoly2;
rpoly1 = rpoly1 + rpoly2; // No problem, calls operator+ for Poly<R>
z4poly = z4poly + z4poly; // No problem, calls operator+ for Poly<Z4>
rploy1 = rpoly1 + z4plot; // compile time error: no operator+ accepts Poly<R>, Poly<Z4>
}

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

אה הא!

לא ידעתי שמותר להכניס את האופרטור < > בתור קידומת לארגומנט של פונקציה. תודה רבה חבר

עדכון: אני מצטט את השורה השניה שלך בקוד

template <typename X> Poly<X> operator+(const Poly<X>& lhs, const Poly<X>& rhs)

החלק המודגש באמת נחוץ?

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

חסר לך סוגריים בקריאה למתודה f אז הקוד הזה לא יעשה את מה שאתה חושב.

אבל בעקרון, כן.

היכולת להעביר קבועים ל-template היא חשובה.

הנה דוגמא:


template <typename T, int SIZE>
class FixedArray
{
T m_data[SIZE]; // define an array of T's with SIZE elements
// ...
};

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

ארכיון

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

×
  • צור חדש...