1 / 32

Generic Programming

This article provides an introduction to generic programming (GP) in C++. It explains what GP is, discusses algorithmic GP, and explores GP techniques and patterns in C++. The article also covers concepts, refinement of concepts, and types that fulfill concepts. It highlights the benefits and limitations of GP and compares it to object-oriented programming (OOP).

trentb
Download Presentation

Generic Programming

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. Generic Programming Johan Torp

  2. Agenda • GP introduction • GP in perspective • Questions * GP = Generic programming in C++

  3. What is GP? • Algorithmic GP • GP techniques & patterns in C++

  4. Polymorphism class BarInterface { virtual void bar() = 0; }; void polymorphicFunction(BarInterface& t) {   ...   t.bar();   ... } template<class T>  void polymorphicFunction(T& t) {   ...   t.bar();   ... }

  5. GP interface is called concept // MyBarConcept // // Has a memberfunction called bar() // ... more assumptions ... // T must fulfill MyBarConcept template<class T> void polymorphicFunction1(T& bar);  // T must fulfill MyBarConcept template<class T> void polymorphicFunction200(T& bar); class MyBar {    void bar(); };

  6. Example concepts Concept DefaultConstructibleCopyable Assignable Addable Convertible to OtherTypeOutputStreamable BarConcept Valid expressions T t; T t2(t1); t1 = t2 t1+t2; static_cast<OtherType>(t); stream << t; t.bar(); Require as little as possible for maximal genericity

  7. Concepts are type requirements • Valid expressions, pre/post conditions & semantics • Additionally: Invariants, associated types, complexity guarantees, etc Concepts in C++ are expressed in documentation Types which fulfill concept C are said to model C Refine new concepts from old ones by adding additional requirements

  8. Input Iterator Description   An Input Iterator is an iterator that may be dereferenced to refer to ... Refinement of   Trivial Iterator Associated Types   Value type - The type obtained by dereferencing ...   Distance type - A signed integral type used to ...  Valid expressions Dereference                         *i   Pre-increment                    ++i Expression semantics Dereference                       Will return a reference to the accessed value type   Pre-increment                    Will ...Complexity guarantees   All operations are amortized constant time

  9. Template instantiation class OneBar { void bar() }; class AnotherBar { void bar() }; Source1.cpp:   polymorphicFunction(int(123)); Source2.cpp:   polymorphicFunction(OneBar());  polymorphicFunction(OneBar());   polymorphicFunction(AnotherBar()); Source3.cpp:   polymorphicFunction(OneBar());

  10. Generalize memcpy void* memcpy(void* region1, const void* region2,size_t n); • Only reads contigous memory • Only writes to contigous memory • Only byte-wise copying  

  11. Minimal requirements of copying • traverse through source sequence • access source elements • copy elements to destination • know when to stop

  12. STL version of copy template <class InputIterator, class OutputIterator>OutputIteratorcopy(InputIterator first, InputIterator pastLast, OutputIterator result){   while (!(first == pastLast)) // Don't require != operator       *result++ = *first++;   return result;}

  13. How pointless?! • Real std::copy is optimized for different types • Solves optimized generic copying once and for all

  14. C++ language features supporting GP Dispatching features • Inheritance • Templates • Namespaces & argument dependent lookup (ADL) • Function & operator overloading • Implicit type conversion • SFINAE • [Partial] template specialization Other useful language features • Dependent types • Template type deduction • Template non-type arguments (compile-time integers, bools, etc) • Template template arguments

  15. GP techniques & patterns • type traits • mix-in classes • policy based design • object generators • enable if • tag dispatching • type erasure • lazy data views  • concept and archetype checking GP related programming models: • template metaprogramming • expression templates to create DSELs • macro metaprogramming

  16. GP in practice • Generalize patterns / boiler plate into generic classes • Library based programming models

  17. GP problems • Compilation & link time • Code size • Language flaws

  18. How much GP can we afford? Maybe we can use more GP because: • Compilers have improved • Well modularized => recompile less • Master/unity builds lessens template bloat • Stability & higher abstraction level allows faster iteration  too • Explicit template instantiation can lessen template bloat • Replacing boilerplate interfaces with type erasure gives similar run-time performance

  19. GP flaws fixed in C++0x • Concept code support • True variadic templates • Type deduction and type inference of named variables • Rvalue references • Preventing template instantiation • Axioms • Object construction improvements • ... and lots more! Compilers are continously adding C++0x features

  20. GP vs OOP: Efficiency and compilation GP more efficient run-time OO code requires less compilation

  21. GP vs OOP: Dependencies • Concrete OO classes and polymorphic code are coupled via the interface  • A type might fulfill/model a concept. Polymorphic code only depends on concept via documentation A.k.a. : ad-hoc polymorphism vs parametric polymorphism

  22. GP vs OOP: Customization points Mix-in classes change interface, state, data layout, etc   template <class MixIn>   class Foo : public MixIn {...}; Type traits & tags can non-intrusively add static information template<class T> struct iterator_traits<T*> { typedef random_access_iterator_tag iterator_category;};

  23. GP vs OOP: Orthogonality template<class Aspect1, class Aspect2, class Aspect3> class TweakableGPClass{ ... }; class TweakableOOClass{    TweakableOOClass(Aspect1&, Aspect2&, Aspect3&); private:   Aspect1& m_a1; ... }; Composition problems • Boiler-plate • Run-time costs (vtable calls, method forwarding, extra state)

  24. GP vs OOP: Dispatch • OOP is only polymorphic on one type - the object type • GP is polymorphic on all parameter types • GP also allow complex dispatch logic! // Default fallback, unless no other function matches better template<class Object1, class Object2> void handleCollision(Object1&, Object2&); // Any object going into a black hole disappears template<Object1> void handleCollision(Object1&, BlackHole&); // Unless it's another black hole -- then we get  // a super nova explosion instead. Yay! template<> void handleCollision(BlackHole&, BlackHole&); // Missiles which hit anything damagable inflicts damage template<class Object2> enable_if<void, isDamagable<Object2>::value> handleCollision(Missile&, Object2&);

  25. GP vs OOP: Simplicity • More power = more ways to shoot ourselves in the foot • OO is less abstract  GP is best suited to build generic libraries - which in turn provide simple and limited programming models

  26. C++ multiparadigm programming • Object orientation • Generic programming • Procedural programming

  27. GP and dynamically typed languages def foo(t):   """t must model bar"""   ...   t.bar()   ... • Compiled separately, extremely fast iteration time • Late binding can provide poor runtime performance • Nothing checked statically, rely on interpreters & unit tests

  28. A reflection on reflection Reflection allows a program to observe and modify its own structure and behavior at runtime • GP dispatch techniques are similar to run-time reflection • GP allows static analysis => understandable behaviour

  29. GP is generative Macro > Template instantiation > Compilation  • Work on multiple "compilation levels" in the same file at the same time

  30. Code generation • Raise abstraction level without runtime penalty • Pay in terms of build system complexity • Identify boiler plate & patterns and generate them

  31. Summary • Concepts are type requirements • Template instantiation • Algorithmic GP  • GP techniques • GP problems • GP classes are highly customizable and reusable • GP vs OOP  • GP is useful for core libraries & algorithms • Dynamic programming languages & reflection • Code generation

  32. Questions?

More Related