369. The difference between generics and templates

נדבר כעת על ההבדל הכללי בין Templateים בC++ לGenerics בC# וJava.

מה זה Template בC++?

Templateים בC++ מאפשרים לנו לכתוב קוד כזה:

1
std::list<Person>* foo = newstd::list<Person>();

זה נראה כמו Generics של Java וC#, אבל מאחורי הקלעים קורים דברים אחרים לגמרי.

זה יותר מזכיר את איך שC# יוצר מחלקות בזמן ריצה מאשר שפיכת הקוד שעושה Java, אבל עדיין זה עוף שונה.

הקומפיילרים של C# וJava מייצרים קוד שמתאים לVirtual machines. אם נכתוב למשל קוד שיש בתוכו את המחלקה Person, בJava או בC# זה יתקמפל לקוד שמכיל מידע אודות המחלקה Person שתפנה לdll המיוצר, והCLR/JVM ידעו לעשות משהו עם זה.

C++ מייצר קוד בשפת מכונה. בניגוד לC# וJava, אין אובייקט שהוא object שכל האובייקטים יורשים ממנו, ואין Virtual Machine שצריכה לדעת על המחלקה Person. גם אין boxing או unboxing ופונקציות לא חייבות להיות שייכות למחלקות.

בגלל זה, הקומפיילר של C++ לא מאפשר להניח הנחות על מה שאפשר לעשות עם templateים –כל קוד שנוכל לכתוב באופן ידני, אפשר לכתוב template שיכתוב אותו בשבילנו.

הדוגמה הברורה ביותר היא הוספת דברים:

בC# וJava, מערכת הטיפוסים הגנרית צריכה לדעת איזה מתודות קיימות עבור מחלקה, וצריכה להעביר את זה לvirtual machine.

הדרך היחידה לעשות היא ע"י כתיבת Hard coded מהי המחלקה הקונקרטית, או ע"י ממשקים.

למשל הקוד הבא לא יתקמפל בC# או Java:

1
int addNames<T>( T first, T second ) { return first.Name() + second.Name(); }

מאחר ולא ידוע למשל אם לטיפוס T אכן יש מתודה בשם Name. אנחנו צריכים לציין לו את זה. בC# אפשר לציין ככה:

1
2
interface IHasName{ string Name(); };
int addNames<T>( T first, T second ) where T : IHasName { .... }

ואז אנחנו צריכים לוודא שכל הדברים שעוברים לaddNames מממשים את הממשק IHasName. בJava הSyntax קצת שונה, אבל סובל מאותם בעיות.

המקרה הקלאסי של הבעיה הזאת היא לנסות לכתוב מתודה כזאת:

1
int addNames<T>( T first, T second ) { return first + second; }

בC# אי אפשר לכתוב קוד כזה כי אי אפשר להגדיר ממשק שיש לו אופרטור של +.

C++ לא סובל מהבעיות האלה – הקומפיילר לא צריך לדאוג להעביר טיפוסים לVirtual Machine. אם לטיפוסים שלנו יש מתודת .Name(), הקוד יתקמפל. אחרת לא.


הטיפים על ההבדלים בין Templateים וGenerics בC#/Java מבוססים על הפוסט הבא בStackOverflow.

סופ"ש גנרי טוב.

שתף