Documentos de Académico
Documentos de Profesional
Documentos de Cultura
programming
2
Introduction
Generic programming becoming a dominant
paradigm in C++
The unexplored power of functional programming
languages
Higher levels of abstraction, design and
reusability
A code-generation mechanism (programs that
generate programs!)
Greater efficiency on what can be found at
compile-time
3
Generic Programming
Early 90s when templates were used for
container<T>
STL
How standardization helped
Design patterns
The ability for templates to model many design patterns
directly
Idea of meta-programming possibility
Boost
Loki
Other libraries
4
Functional programming
Functional programming is there for a long time
Lambda calculus, Lisp, Scheme, Haskell…
functions are treated as regular values
Functional programming advantages
Idioms, patterns and techniques
Polymorphic “higher-order” functions
Functions that take other functions as arguments and
returns functions!
The ‘lambda’ thing
Creating functions ‘on-the-fly’ is very common
TMP is inspired by functional programming
5
Abstraction, Design and
Reusability
The much hyped ‘component software’
‘Plug-and-play’ software
Design Patterns
The GoF (Gang of Four) ‘Design Patterns’ book
Elements of reusable software
Language independent
Library as the basis of reusable software (as
opposed to frameworks)
The proverbial ‘adding a level of indirection’ as a
means for better reusable components
6
Program Generating Programs
9
Parameterized Types
10
“Parameterized” Stack
template <class T>
class stack{
stack(int start_size = 10);
int is_empty() const;
int is_full() const;
// these members remain the same
void push(const T& t);
T& pop();
// templatizing the required members
private:
T* stack; // Note T* here
int top_of_stack;
int size;
};
11
Comparing with Java example
Making use of Object base class
Not type safe – the single biggest problem Java
programmers face after performance issues
“Generic types” for typesafety – not for genericity
per se
class Stack<Type> {
public void push(Type t){ /* … */ }
public Type pop() { /*... */ }
private int topOfStack;
private int size = 10;
T stack []; { stack = new stack[size]; }
}
Similarity of C++ templates and Java generics end
here! 12
Templates for Reusable
Components
An example: Making classes non-inheritable
C++ has no equivalent of Java's final
(for class non-inheritable classes)
You can make destructor of base class private
disallows creating objects (except in heap)
Disadvantage: imposes constraints
on kind of type of allocation being done.
13
Example: ‘Plain’ Code
class Usable;
struct Usable_lock {
friend class Usable;
private:
Usable_lock(){}
// copy ctr also private
};
struct Usable : public virtual Usable_lock{
Usable(); // copy ctr also public
// ...
};
14
Example: ‘Plain’ Code …
Usable a;
DD dd;
// error: DD::DD() cannot access
// Usable_lock::Usable_lock()
// which is a private member
15
Example: ‘Templatized’ Code
template <typename T> struct nonderivable;
16
Example: ‘Templatized’ Code …
class Test: nonderivable <Test> {};
Test t;
// okay, you can create objects
Deri d;
// Error, in-accessible base class constructor.
//See, compiler won't allow you to do so.
17
Template Template Parameters
18
Template Template Parameters
…
template <
typename type,
template <typename T, typename A>
class container = std::vector,
// default is vector if you don’t provide
one explicitly
typename allocator = std::allocator<type> >
class my_container {
container<type, allocator> _container;
//instantiate template template parameter
};
// instantiation of my_container
my_container<int, std::list> container;
19
Template Template P arameters …
20
Meta-Programming
21
How it started?
Started with a mistake which led to infinite
recursion in instantiating templates
Initial examples seem simple and for fun
But has appeal for serious design and industrial
use
Earliest documented example is by Erwin
Unruh for computing Prime numbers.
Initially popularized by Todd Veldhuizen
Used in Blitz++
22
Serendipity
Infinite instantiation:
template <int n>
struct Factorial {
static const int val =
n * Factorial<n-1>::val;
};
static const int val = Factorial<3>::val;
aCC complains:
Error 588:Template generation nesting too deep;
discovered during generation of specialization
'Factorial<(int)-251>'. You may have an
infinite recursive generation.
23
Adding Terminating Condition
template <int n>
struct Factorial {
static const int val = n * Factorial<n-1>::val;
};
template <>
struct Factorial<1> {
static const int val = 1;
};
24
Programming Constructs
25
Template for If-Then
One example: Representing If-Then-Else
condition
How to select a class member type based on a
condition?
Say signed or a unsigned one
One way to achieve this is to have a traits class and
make the selection over there using a boolean non-type
parameter (basis for typetraits library).
Part of all major meta-programming libraries (Loki,
Boost etc).
26
Template for If-Then
template <typename T, bool isSigned>
struct myMemberSignTrait{
typedef signed T signType;
}; // selected in case isSigned is true
27
Template for If-Then
template <typename T, bool isSigned>
class myContainer {
typedef myMemberSignTrait<T, isSigned>
memberSignTrait;
typedef typename containerMemberTrait::signType
signType;
signType member;
// member will be signed or unsigned
// depending on the isSigned bool value
};
28
Improved If-Then
Not elegant to extend (not scalable)
Better to have a separate template class for
doing such a selection.
template <typename T, typename F, bool isSigned>
struct if_select {
typedef T type;
}; // selected in case isSigned is true
29
Improved If-Then
template <typename T, bool isSigned>
class myContainer {
typedef typename if_select<signed T, unsigned T,
isSigned>::type signType;
signType member;
// ...
};
30
Still better If-Then
template <bool isSigned>
struct if_cond {
template<typename T, typename F>
struct then_select {
typedef T type;
};
}; // selected in case isSigned is true
31
Still better If-Then
template <typename T, bool isSigned>
class myContainer {
typedef typename if_cond<isSigned>::template
then_select<signed T, unsigned T>::type signType;
signType member;
// ...
};
32
Usage Example – if_select
class CompactingGC {
void GC() { … }
};
class MarkAndSweepGC {
void GC() { … }
};
33
Another Example- isPointer
template <typename T>
class type_traits{
template <class U> struct pointer_traits{
static const int result = false;
}
// specialization for pointer type
template <class U *> struct pointer_traits{
static const int result = true;
}
public:
static const int is_pointer = pointer_traits<T>::
result;
};
// const bool is_ptr =
type_traits<someTypedef>::is_pointer;
34
Application
of meta-programming
35
Conversion Check Tool
template <class T, class U>
class Conversion{
typedef char Small;
class Big { char dummy[2]; }
static Small Test(U);
static Big Test(...);
static T MakeT();
public:
enum { exists = sizeof(Test(MakeT())) ==
sizeof(Small) };
};
36
Unrolling vector addition
inline void addVect(int size, double* a, double* b,
double* c) {
while (size--)
*c++ = *a++ + *b++;
}
37
Template Unrolling
template<int size>
inline void addVect(double* a, double* b,
double* c) {
*c = *a + *b;
addVect<size-1>(a+1, b+1, c+1);
}
template<>
inline void addVect(double* a, double* b,
double* c) { }
addVect<3>(a, b, c);
38
Effect of unrolling
addVect<3>(a, b, c);
*c = *a + *b;
addVect<2>(a+1, b+1, c+1);
*(c+1) = *(a+1) + *(b+1);
addVect<1>(a+2, b+2, c+2);
*(c+2) = *(a+2) + *(b+2);
addVect<0>(a+3, b+3, c+3);
39
Dot Product
template <int DIM, typename T>
struct DotProduct {
static T result (T* a, T* b){
return *a * *b +
DotProduct<DIM-1,T>::result(a+1,b+1);
}
};
40
Dot Product
template <int DIM, typename T>
inline T dot_product (T* a, T* b) {
return DotProduct<DIM,T>::result(a,b);
}
// usage:
int main() {
int a[3] = { 1, 2, 3};
int b[3] = { 5, 6, 7};
std::cout << "dot_product(3,a,b) = "
<< dot_product(3,a,b) << '\n';
std::cout << "dot_product(3,a,a) = " <<
dot_product(3,a,a);
}
41
For Loop Unrolling
template<int n, class B>
struct FOR {
static void loop(int m) {
for (int i = 0; i < m/n; i++) {
UNROLL<n, B>::iteration(i * n);
}
for (int i = 0; i < m%n; i++) {
B::body(n * m/n + i);
}
};
42
Loop Unrolling …
template <int n, class B>
struct UNROLL {
static void iteration(int i) {
B::body(i);
UNROLL<n-1, B>::iteration(i + 1);
}
};
template <class B>
struct UNROLL<0, B> {
static void iteration(int i) { }
};
43
Meta-programming
Libraries
44
Loki
By Andrei Alexaderescu
“Modern C++ Design” book Covers in Detail
Important components:
Small object allocator
Typetraits and Typelists
Implementing Singletons
Smart Pointers
Object Factories
Visitor
45
Boost
Major and wildly growing library
Compatible with STL
Important components:
Regex
Threads
Typetraits
Lambda
Binder
Function Object Wrapper
FC++ (Functional C++)
…
46
Future of
Meta-programming
47
Future Looks Rosy
Templates as a means for reusable and adaptive
software
Generic programming
poised to become dominant paradigm in C++
Metaprogramming libraries
Started - to be used widely
10 Boost libraries – candidates for becoming part
standard
More and more programmers are attracted towards
Functional programming in C++
From structured => object-oriented => generic =>
functional ! Don’t faint ;-)
48
But it won’t be easy
49