32
C++ Template Metaprogramming in 15ish Minutes

Template Metaprogramming

Embed Size (px)

DESCRIPTION

c++ templates

Citation preview

Page 1: Template Metaprogramming

C++ Template Metaprogramming in 15ish Minutes

Page 2: Template Metaprogramming

C++ Template Metaprogramming in 15ish Minutes

Page 3: Template Metaprogramming

A program is a sequence of instructions which creates and modifies data.

Page 4: Template Metaprogramming

A metaprogram is a sequence of instructions which creates and modifies programs.

Page 5: Template Metaprogramming

Why would you ever want to do this?

Page 6: Template Metaprogramming

Machine Code

Assembly

C

C++

Page 7: Template Metaprogramming

Metaprogramming introduces new abstractions into the host language.

Page 8: Template Metaprogramming

So what exactly is template metaprogramming?

Page 9: Template Metaprogramming

How C++ Templates Work

C++ Compiler

C++SourceCode

TemplateCompiler

MachineCode

TemplateCompiler

This is a metaprogramming step!

Page 10: Template Metaprogramming

A template metaprogram is a C++ program that uses templates to generate customized C++ code

at compile-time.

Page 11: Template Metaprogramming

A new abstraction: policies.

Page 12: Template Metaprogramming

template <typename T> class Vector {public: T getAt(int index); void setAt(int index, T value);

/* ... etc. ... */};

Page 13: Template Metaprogramming

Vector

Type T

Range Checking

Synchronization

Page 14: Template Metaprogramming

Templates are parameterized over types, not behaviors.

Page 15: Template Metaprogramming

A policy class is a type that implements a particular behavior.

Page 16: Template Metaprogramming

template <typename T> class Vector {public: T getAt(int index); void setAt(int index, T value);

/* ... etc. ... */};

Page 17: Template Metaprogramming

template <typename T, typename RangePolicy, typename LockingPolicy>class Vector {public: T getAt(int index); void setAt(int index, T value);

/* ... etc. ... */};

Page 18: Template Metaprogramming

template <typename T, typename RangePolicy, typename LockingPolicy>class Vector: public RangePolicy, public LockingPolicy {public: T getAt(int index); void setAt(int index, T value);

/* ... etc. ... */};

Page 19: Template Metaprogramming

Sample Range Policy

class ThrowingErrorPolicy{protected: ~ThrowingErrorPolicy() {}

static void CheckRange(int pos, int numElems) { if(pos >= numElems) throw std::out_of_bounds("Bad!"); }};

Page 20: Template Metaprogramming

Another Sample Range Policy

class LoggingErrorPolicy{public: void setLogFile(std::string filename); protected: ~LoggingErrorPolicy(); void CheckRange(int pos, int numElems) { if(pos >= numElems && output != 0) *log << "Error!" << std::endl; }private: std::ofstream* log;};

Page 21: Template Metaprogramming

Another Sample Range Policy

class LoggingErrorPolicy{public: void setLogFile(std::string filename);protected: ~LoggingErrorPolicy(); void CheckRange(int pos, int numElems) { if(pos >= numElems && output != 0) *log << "Error!" << std::endl; }private: std::ofstream* log;};

Page 22: Template Metaprogramming

template <typename T, typename RangePolicy, typename LockingPolicy>T Vector<T, RangePolicy, LockingPolicy>:: getAt (int position){ LockingPolicy::Lock lock; ErrorPolicy::CheckBounds(position, this->size); return this->elems[position];}

Implementer Code

Page 23: Template Metaprogramming

template <typename T, typename RangePolicy, typename LockingPolicy>T Vector<T, RangePolicy, LockingPolicy>:: getAt (int position){ LockingPolicy::Lock lock; ErrorPolicy::CheckBounds(position, this->size); return this->elems[position];}

Implementer Code

Page 24: Template Metaprogramming

template <typename T, typename RangePolicy, typename LockingPolicy>T Vector<T, RangePolicy, LockingPolicy>:: getAt (int position){ LockingPolicy::Lock lock; RangePolicy::CheckRange(position, this->size); return this->elems[position];}

Implementer Code

Page 25: Template Metaprogramming

Client Code

int main(){ Vector<int, ThrowingErrorPolicy, NoLockingPolicy> v; for(size_t k = 0; k < kNumElems; ++k) v.push_back(k);

/* ... etc. ... */

return 0;}

Page 26: Template Metaprogramming

Or this...

int main(){ Vector<int, AssertingErrorPolicy, PThreadLockingPolicy> v; for(size_t k = 0; k < kNumElems; ++k) v.push_back(k);

/* ... etc. ... */

return 0;}

Page 27: Template Metaprogramming

Or even this...

int main(){ Vector<int, NoErrorPolicy, NoLockingPolicy> v; for(size_t k = 0; k < kNumElems; ++k) v.push_back(k);

/* ... etc. ... */

return 0;}

Page 28: Template Metaprogramming

Policy classes beat the combinatorial explosion of possible implementations.

Page 29: Template Metaprogramming

This is not possible withouttemplate metaprogramming.

Page 30: Template Metaprogramming

But this is just a taste of what's possible with template metaprogramming.

Page 31: Template Metaprogramming

Template Metaprogramming Does:● Compile-time dimensional analysis.● Multiple dispatch.● Design patterns.● Code optimization.● Lexing and parsing.● And so much more...

Page 32: Template Metaprogramming

Recommended Reading● More template

metaprogramming than you'll know what to do with.

● Very advanced material; be prepared to be overwhelmed!

● Considered the seminal work in modern C++ programming.