1. Trang chủ
  2. » Giáo Dục - Đào Tạo

Template Metaprogramming In C++

113 465 0

Đang tải... (xem toàn văn)

Tài liệu hạn chế xem trước, để xem đầy đủ mời bạn chọn Tải xuống

THÔNG TIN TÀI LIỆU

Thông tin cơ bản

Định dạng
Số trang 113
Dung lượng 252,55 KB

Các công cụ chuyển đổi và chỉnh sửa cho tài liệu này

Nội dung

Providing arguments to a template instantiates the template with those arguments.. template template void Vector::insertiterator where, }... template struct iterator_traits { typedef

Trang 1

Template Metaprogramming in C++

CS242, Fall 2009 Keith Schwarz

Trang 2

Preliminaries

Trang 3

A C++ template is a type or function

parameterized over a set of types, functions, or

constants.

Trang 4

template <typename One, typename Two>

Trang 5

template <typename One, typename Two>

Trang 6

template <typename One, typename Two>

Trang 7

Providing arguments to a template instantiates

the template with those arguments Instantiation

occurs at compile-time.

Trang 9

Template Specialization

● A version of a template to use when a specific pattern of arguments are supplied.

● Structure independent of primary template.

● Can add/remove functions from interface, etc.

Full specialization used when all arguments are

specified.

Partial specialization used when arguments

have a particular structure.

Trang 13

A metaprogram is a program that produces or

manipulates constructs of a target language.

Trang 14

A template metaprogram is a C++ program that

uses templates to generate customized C++ code

at compile-time.

Trang 15

Why would you ever want to do this?

Trang 17

Template Metaprogramming In Action

Part One: Policy Classes

Trang 18

template <typename T> class Vector

{

public:

/* ctors, dtor, etc */

T& operator[] (size_t);

const T& operator[] (size_t) const;

void insert(iterator where,

const T& what);

/* etc */

};

Trang 19

Type T

Range Checking

Synchronization

Trang 20

Templates are parameterized over types, not

behaviors.

Trang 21

A policy class is a type that implements a

particular behavior.

Trang 22

/* ctors, dtor, etc */

T& operator[] (size_t);

const T& operator[] (size_t) const;

void insert(iterator where,

const T& what);

/* etc */

};

Trang 23

/* ctors, dtor, etc */

T& operator[] (size_t);

const T& operator[] (size_t) const;

void insert(iterator where,

const T& what);

/* etc */

};

Trang 24

/* ctors, dtor, etc */

T& operator[] (size_t);

const T& operator[] (size_t) const;

void insert(iterator where,

const T& what);

/* etc */

};

Trang 25

Sample Range Policy

if(pos >= numElems)

throw std::out_of_bounds("Bad!"); }

};

Trang 26

Another Sample Range Policy

private:

std::ofstream* log;

};

Trang 27

Another Sample Range Policy

private:

Trang 31

/* etc */

return 0;

}

Trang 32

template <

typename T,

typename RangePolicy = NoErrorPolicy,

typename LockingPolicy = NoLockingPolicy>class Vector: public RangePolicy,

public LockingPolicy

{

public:

/* ctors, dtor, etc */

T& operator[] (size_t);

const T& operator[] (size_t) const;

void insert(iterator where,

const T& what);

void erase(iterator where);

/* etc */

};

Trang 33

Updated Client Code

int main()

{

Vector<int, ThrowingErrorPolicy> v;

for(size_t k = 0; k < kNumElems; ++k) v.push_back(k);

/* etc */

return 0;

}

Trang 34

Summary of Policy Classes

Identify mutually orthogonal behaviors in a

class.

Specify an implicit interface for those

behaviors.

Parameterize a host class over each policy.

Use multiple inheritance to import the policies

into the host.

Trang 35

Template Metaprogramming In Action

Part Two: Traits Classes and Tag Dispatching

Trang 36

template </* */>

class Vector: /* */

{

public:

void insert(iterator where,

const T& what);

template <typename IteratorType>

void insert(iterator where,

IteratorType start, IteratorType stop);

/* */

};

Trang 37

template < >

template <typename Iter>

void Vector< >::insert(iterator where,

}

Trang 38

template < >

template <typename Iter>

void Vector< >::insert(iterator where, Iter start,

Iter stop )

{

/* Insert elements one at a time */ for(; start != stop; ++start, ++where) where = insert(where, start);

}

Trang 39

template <typename Iter> struct iterator_traits {

typedef typename Iter::difference_type

difference_type;

typedef typename Iter::value_type value_type; typedef typename Iter::pointer pointer;

typedef typename Iter::reference reference;

typedef typename Iter::iterator_category

iterator_category;

};

/* Specialization for raw pointers */

template <typename T> struct iterator_traits<T*> {

typedef ptrdiff_t difference_type;

typedef T value_type;

typedef T* pointer;

typedef T& reference;

Trang 40

A traits class is a template type that exports

information about its parameters.

Trang 41

Schematic of Traits Classes

Language Construct Metainformation

Traits Class

Trang 42

template <typename Iter> struct iterator_traits {

typedef typename Iter::difference_type

difference_type;

typedef typename Iter::value_type value_type; typedef typename Iter::pointer pointer;

typedef typename Iter::reference reference;

typedef typename Iter::iterator_category

iterator_category;

};

/* Specialization for raw pointers */

template <typename T> struct iterator_traits<T*> {

typedef ptrdiff_t difference_type;

Trang 43

template <typename Iter> struct iterator_traits {

typedef typename Iter::difference_type

difference_type;

typedef typename Iter::value_type value_type; typedef typename Iter::pointer pointer;

typedef typename Iter::reference reference;

iterator_category;

};

/* Specialization for raw pointers */

template <typename T> struct iterator_traits<T*> {

typedef ptrdiff_t difference_type;

typedef T value_type;

typedef T* pointer;

typedef T& reference;

Trang 45

A tag class is a (usually empty) type encoding

semantic information.

Trang 46

Tag dispatching is function overloading on tag

classes.

Trang 47

template < >

template <typename Iter>

void Vector< >::insert(iterator where,

Trang 48

template < >

template <typename Iter>

void Vector< >::insert(iterator where,

Trang 49

template < >

template <typename Iter>

void Vector< >::doInsert(iterator where,

Iter start, Iter stop,

std::input_iterator_tag)

{

/* Insert elements one at a time */

for(; start != stop; ++start, ++where)

where = insert(where, start);

}

template < >

template <typename Iter>

void Vector< >::doInsert(iterator where,

Iter start, Iter stop,

std::forward_iterator_tag)

{

/* more complex logic to shift everything

* down at the same time

Trang 50

template < >

template <typename Iter>

void Vector< >::doInsert(iterator where,

Iter start, Iter stop,

{

/* Insert elements one at a time */

for(; start != stop; ++start, ++where)

where = insert(where, start);

}

template < >

template <typename Iter>

void Vector< >::doInsert(iterator where,

Iter start, Iter stop,

std::forward_iterator_tag) {

/* more complex logic to shift everything

* down at the same time

*/

}

Trang 51

Schematic of Tag Dispatching

Trang 52

Summary of Tag Dispatching

Define a set of tag classes encoding semantic

information.

● Provide a means for obtaining a tag from each

relevant type (often using traits classes)

Overload the relevant function by accepting

different tag types as parameters.

● Call the overloaded function using the tag

associated with each type.

Trang 53

Template Metaprogramming In Action

Part Three: Typelists

Trang 54

struct Nil {};

template <typename Car, typename Cdr> struct Cons {};

The Typelist

Trang 55

>

>

Sample Typelist

Trang 56

#define LIST0() Nil

#define LIST1(a) Cons<a, LIST0()>

#define LIST2(a, b) Cons<a, LIST1(b)>

#define LIST3(a, b, c) Cons<a, LIST2(b, c)>

#define LIST4(a, b, c, d) Cons<a, LIST3(b, c, d)> /* etc */

LIST6(int, double, float, char, short, long)

A Simplification

Trang 57

Car/Cdr Recursion with Templates

template <typename> struct Length;

Trang 58

Car/Cdr Recursion with Templates

template <typename> struct Length;

template <> struct Length<Nil>

Trang 59

Car/Cdr Recursion with Templates

template <typename> struct Length;

template <> struct Length<Nil>

Trang 60

Length<LIST3(int, double, string)>

Trang 61

Length<LIST3(int, double, string)>

Trang 62

Typelists and template specialization allow us to write templates whose instantiation causes a

chain reaction of further instantiations.

Trang 63

This lets us construct arbitrarily complicated

structures at compile-time.

Trang 69

Can we automatically generate a visitor for a type

hierarchy?

Trang 70

Yes!

Trang 71

Idea: Create a type parameterized over a

typelist that has one instance of visit for each

type in the list.

Trang 72

template <typename List> class Visitor;

template <typename T> class Visitor<Cons<T, Nil> > {

Trang 73

template <typename List> class Visitor;

template <typename T> class Visitor<LIST1(T) > {

Trang 74

template <typename List> class Visitor;

template <typename T> class Visitor<LIST1(T) >

template <typename Car, typename Cdr>

class Visitor<Cons<Car, Cdr> > : public Visitor<Cdr> {

public:

virtual void visit(Car*) = 0;

using Visitor<Cdr>::visit;

};

Trang 75

Visitor<LIST4(MulExpr, SubExpr, DivExpr, ExprNode)>

virtual void visit(MulExpr*)

Visitor<LIST3(SubExpr, DivExpr, ExprNode)>

virtual void visit(SubExpr*)

Trang 76

Visitor<LIST5(AddExpr, MulExpr, SubExpr, DivExpr, ExprNode)>

virtual void visit(AddExpr*) virtual void visit(MulExpr*) virtual void visit(SubExpr*) virtual void visit(DivExpr*) virtual void visit(ExprNode*)

Trang 77

Summary of Typelists

Construct types corresponding to LISP-style

lists whose elements are types.

Use template specialization to model car/cdr

recursion.

Trang 78

The Limits of Template Metaprogramming

Trang 79

Σ is the input alphabet

Γ is the tape alphabet

$ ∈ Γ – Σ is the start symbol

● q0 ∈ Q is the start state

Trang 80

Queue Automaton Example

Trang 81

Queue Automaton Example

Trang 82

Queue Automaton Example

Trang 83

Queue Automaton Example

Trang 84

Queue Automaton Example

Trang 85

Queue Automaton Example

Trang 86

Queue Automaton Example

Trang 87

Queue Automaton Example

Trang 88

Queue Automaton Example

Trang 89

Queue Automaton Example

Trang 90

Queue Automaton Example

Trang 91

Queue Automaton Example

Trang 92

Queue Automaton Example

Trang 93

Queue Automaton Example

Trang 94

Queue Automaton Example

Trang 95

Queue Automaton Example

Trang 96

Queue Automaton Example

Trang 97

Queue Automaton Example

Trang 98

Queue Automaton Example

Trang 99

Queue Automaton Example

Trang 100

Queue Automaton Example

Trang 101

Queue Automaton Example

Trang 102

Queue Automaton Example

Trang 103

Can we simulate a queue automaton with a

template metaprogram?

Trang 104

Yes!

Trang 105

template <typename, typename> struct Concat;

template <typename T> struct Concat<Nil, T>

Trang 107

Encoding the Transition Table δ

template <typename, typename> struct Delta;

/* Specialize Delta for each entry in δ */

template <> struct Delta<State1, Symbol1>

{

typedef State2 nextState;

typedef LIST2(Symbol1, Symbol1) nextSymbols; };

template <> struct Delta<State1, Symbol2>

{

typedef State1 nextState;

typedef LIST0() nextSymbols;

Trang 108

Running the Queue Automaton

template <typename State, typename Queue>

struct RunAutomaton;

template <typename State>

struct RunAutomaton<State, Nil>

{

typedef void result;

};

template <typename Car, typename Cdr, typename State>

struct RunAutomaton<State, Cons<Car, Cdr> >

{

typedef typename Delta<State, Car>::nextState newState;

typedef typename Delta<State, Car>::nextSymbols newSym; typedef typename Concat<Cdr, newSym>::result newQueue;

typedef

typename RunAutomaton<newState, newQueue>::result result; };

Trang 109

Starting the Queue Automaton

Trang 110

A Turing machine can simulate C++ templates C++ templates can simulate queue automata Queue automata can simulate Turing machines.

C++ templates are Turing-complete.

Trang 111

In other words, the C++ type system has the

same computational capabilities as C++.

Trang 113

Questions?

Ngày đăng: 30/10/2015, 18:08

TỪ KHÓA LIÊN QUAN

w