Download presentation
Presentation is loading. Please wait.
Published byJared McGee Modified over 9 years ago
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 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 void polymorphicFunction1(T& bar); // T must fulfill MyBarConcept template void polymorphicFunction200(T& bar); class MyBar { void bar(); };
6
Example concepts Concept DefaultConstructible Copyable Assignable Addable Convertible to OtherType OutputStreamable BarConcept Valid expressions T t; T t2(t1); t1 = t2 t1+t2; static_cast (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 OutputIterator copy(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 Foo : public MixIn {...}; Type traits & tags can non-intrusively add static information template struct iterator_traits { typedef random_access_iterator_tag iterator_category;};
23
GP vs OOP: Orthogonality template 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 void handleCollision(Object1&, Object2&); // Any object going into a black hole disappears template 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 enable_if ::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?
Similar presentations
© 2025 SlidePlayer.com. Inc.
All rights reserved.