advanced software engineering with c templates
play

Advanced Software Engineering with C++ Templates Templates Thomas - PowerPoint PPT Presentation

Advanced Software Engineering with C++ Templates Templates Thomas Gschwind <thg at zurich dot ibm dot com> Templates Polymorphisms Specialization Declaration and Use Classes and Members Ambiguities An Example (pvector)


  1. Advanced Software Engineering with C++ Templates Templates Thomas Gschwind <thg at zurich dot ibm dot com>

  2. Templates § Polymorphisms § Specialization § Declaration and Use § Classes and Members § Ambiguities § An Example (pvector) Th. Gschwind. Advanced Software Engineering with C++ Templates. 91

  3. Types of Polymorphisms § “Ad-hoc” • Overloading • Statically resolved by the compiler (using argument types) § Dynamic • Using virtual member functions • Method to be invoked identified during run-time (using a virtual method table) § Static or Parametric • Using templates • Function to be invoked identified statically • Concrete Functions/Classes are generated for the individual parameter types Th. Gschwind. Advanced Software Engineering with C++ Templates. 92

  4. Templates – Why? § Allow to implement a function or class for a set of types and not just a ”single” hard-coded type • Writing min, max, swap, gcd, and lcm for all kinds of types is tedious • Sort of like Lisp, Smalltalk, Python, Ruby, you name it… • Just more efficiently § Support generic programming • Many functions are the same independently of the data type • Can influence the compiler’s code generation with specially crafted templates Th. Gschwind. Advanced Software Engineering with C++ Templates. 93

  5. Templates: Declaration and Definition This is “old style”, typename is “more” template<class T> correct, but many people still prefer class. If you use an antiquated C++ compiler you may T min( T a, T b) { have to use class. return a<b ? a : b; } § Specify type as additional compile-time parameters • Types used with this template have to provide the routines used by the template • In this case, the comparison operator and a copy constructor § Are checked and resolved statically (during compile time) • Function calls can be resolved during compilation time § The definition must be available to the compiler Th. Gschwind. Advanced Software Engineering with C++ Templates. 94

  6. Templates: Use § When invoking templates we can specify as additional (compile- time) parameter the type of the template to use template < typename T> T min(T a, T b) { return a<b?a:b; } const double pi=3.141596; void f() { min<double>(2.718282, 1.0); min<char>('a', 'z'); min<int>(1, 26); min<double>(pi, 2.718282); min<int>('a', 26); min<double>(2.718282, 1); } Th. Gschwind. Advanced Software Engineering with C++ Templates. 97

  7. Templates: Use (cont’d) § In most cases, template parameters are deduced by the compiler • Deduction must be unambiguous • Otherwise, the ambiguity needs to be resolved manually template < typename T> template < typename T> inline T min(T a, T b) { inline T min(T a, T b) { return a<b?a:b; return a<b?a:b; } } const double pi=3.141596; const double pi=3.141596; void f() { void f() { min(2.718282, 1.0); // ok min(2.718282, 1.0); min('a', 'z'); // ok min('a', 'z'); min(1, 26); min(1, 26); // ok min(pi, 2.718282); min(pi, 2.718282); // ok min('a', 26); // error, ambiguous min('a', 26); min(2.718282, 1); min(2.718282, 1); // error, ambiguous } } Th. Gschwind. Advanced Software Engineering with C++ Templates. 98

  8. Templates: Resolving Ambiguities § Unlike “normal” functions, there is no implicit conversion for parameters passed to templates § Explicit • If necessary min<int>('a', 26); • Or even if unnecessary min<const double>(pi, 2.718282); Th. Gschwind. Advanced Software Engineering with C++ Templates. 100

  9. Mixing Templates and Non-Templates § Templates and non-templates can be mixed § Can define a template-based function min § And define a non template-based function min at the same time § Non-templates are preferred over templates if no type conversion necessary template < typename T> T min(T a, T b) { return a<b ? a : b; } double min(double a, double b) { return a<b ? a : b; } Th. Gschwind. Advanced Software Engineering with C++ Templates. 101

  10. Templates: Resolving Ambiguities (cont‘d) § We can create separate helper functions • Helper functions may be based on the underlying template int min( int x, int y) { return min< int >(x, y); } double min( double x, double y) { return min< double >(x, y); } § This approach not only looks tedious but is also error-prone, clumsy, … Th. Gschwind. Advanced Software Engineering with C++ Templates. 102

  11. min Template – A Problem? § What happens if we use it with (C-style) strings? cout << min("Hello", "World") << endl; § Based on the behavior of the other data types, we would expect a lexicographical Memory comparison of the arguments 0x1000 World § However, compares the addresses where the strings are 0x2000 Hello stored • Returns the string stored at the smaller address Th. Gschwind. Advanced Software Engineering with C++ Templates. 103

  12. Specialization ( 1 st Attempt ) § Templates and non-templates can be mixed § Define a non template-based function min for C strings template < typename T> T min(T a, T b) { return a<b ? a : b; } char *min( char *a, char *b) { return strcmp(a, b)<0 ? a : b; } const char *min( const char *a, const char *b) { return strcmp(a, b)<0 ? a : b; } #include "min.h" void foo(char *x, char *y, const char *z) { cout << min(x,y) << endl; // yes cout << min(x,z) << endl; // yes cout << min<const char*>(x,z) << endl; // compiles but no } We are asking for the template, so we get the template … Th. Gschwind. Advanced Software Engineering with C++ Templates. 104

  13. Template Specialization ( 2 nd and Final Attempt ) § C++ allows us to specialize an existing template for specific types template < typename T> T min(T a, T b) { return a<b ? a : b; } template<> char *min<char *>(char *a, char *b) { return strcmp(a, b)<0 ? a : b; } template<> const char *min<const char *>(const char *a, const char *b) { return strcmp(a, b)<0 ? a : b; } Compiler error; as we discussed, there is no #include "min.h" implicit parameter void foo(char *x, char *y, const char *z) { conversions for templates. cout << min(x, y) << endl; // yes cout << min(x, z) << endl; // error cout << min<const char*>(x, z) << endl; // yes } Th. Gschwind. Advanced Software Engineering with C++ Templates. 105

  14. Templates: Classes and Members § Works exactly the same § Simply put template <typename T, typename U, …> in front of the declaration § It is even OK, to introduce new template parameters for individual member functions § Before C++17 no template parameter deduction for constructors • Template arguments need to be invoked when constructing an object pair<int, bool>(1, false) • Helper functions such as make_pair(1, false) § Template parameter deduction of constructors [C++17] • Allows developers to write pair(1, false) Th. Gschwind. Advanced Software Engineering with C++ Templates. 106

  15. A Persistent pvector Class § We want to implement a persistent version of C++’s vector class § Reads all elements from a file in the constructor § Writes all elements back to the file in the destructor template < typename T> class pvector { string filename; vector<T> v; … public : pvector(string fname) : filename(fname) { readvector(); } ~pvector() { writevector(); } void push_back( const T &el) { v.push_back(el); } void pop_back() { v.pop_back(); } … Th. Gschwind. Advanced Software Engineering with C++ Templates. 107

  16. A Persistent pvector Class (cont’d) template < typename T> class pvector { string filename; vector<T> v; void readvector() { ifstream ifs(filename); for (;;) { T x; ifs >> x; if(!ifs.good()) break; v.push_back(x); } } void writevector() { ofstream ofs(filename); typename vector<T>::iterator fst=v.begin(), lst=v.end(); while (fst!=lst) ofs << *fst++ << endl; OR starting with C++11, simply: } for ( const T &elem : v) ofs << elem << endl; … Th. Gschwind. Advanced Software Engineering with C++ Templates. 108

  17. A Persistent pvector Class (cont’d) § What happens if we pass the pvector around? void foo(pvector< int > pv) { if (pv.size()>0) cout << pv[0] << endl; pv.push_back(17); } int main( int argc, char *argv[]) { pvector< int > pv("/tmp/pvector-int.txt"); foo(pv); } § Hence, maybe we want to disable the copy-constructor for pvector<T> Th. Gschwind. Advanced Software Engineering with C++ Templates. 109

  18. BREAK? Th. Gschwind. Advanced Software Engineering with C++ Templates. 110

  19. Advanced Software Engineering with C++ Templates Separate Compilation Thomas Gschwind <thg at zurich dot ibm dot com>

  20. Separate Compilation § Compared to Java § Variables § Routines (Functions & Operators) § Types (Structures, Classes) § Makefiles Th. Gschwind. Advanced Software Engineering with C++ Templates. 112

  21. Separate Compilation § Why? • Having only one source file is unrealistic • Break the code up into its logical structure • Reduction of compile time • Only changed parts need to be recompiled § How? • Use multiple source files • Compiler needs to know about • Functions and variables provided by other compilation units • Their signatures and types Th. Gschwind. Advanced Software Engineering with C++ Templates. 113

Download Presentation
Download Policy: The content available on the website is offered to you 'AS IS' for your personal information and use only. It cannot be commercialized, licensed, or distributed on other websites without prior consent from the author. To download a presentation, simply click this link. If you encounter any difficulties during the download process, it's possible that the publisher has removed the file from their server.

Recommend


More recommend