c++ template metaprogramming -...
TRANSCRIPT
![Page 1: C++ Template Metaprogramming - unipi.itdidawiki.cli.di.unipi.it/.../pa/templatemetaprogramming.pdf · C++ as a Two-Level Language Dynamic code is compiled and executed at runtime](https://reader030.vdocuments.site/reader030/viewer/2022041103/5f01bd4a7e708231d400cde7/html5/thumbnails/1.jpg)
Static Metaprogramming in C++Haoyuan Li
Dipartimento di Informatica
Università di Pisa
Università di Pisa
![Page 2: C++ Template Metaprogramming - unipi.itdidawiki.cli.di.unipi.it/.../pa/templatemetaprogramming.pdf · C++ as a Two-Level Language Dynamic code is compiled and executed at runtime](https://reader030.vdocuments.site/reader030/viewer/2022041103/5f01bd4a7e708231d400cde7/html5/thumbnails/2.jpg)
Generic versus Generative
Generic programming focuses on
representing families of domain concepts
(parameterization)
Generative programming also includes the
process of creating concrete instances of
concepts (metaprogramming)
In generative programming, the principles
of generic programming are applied to the
solution space
1
![Page 3: C++ Template Metaprogramming - unipi.itdidawiki.cli.di.unipi.it/.../pa/templatemetaprogramming.pdf · C++ as a Two-Level Language Dynamic code is compiled and executed at runtime](https://reader030.vdocuments.site/reader030/viewer/2022041103/5f01bd4a7e708231d400cde7/html5/thumbnails/3.jpg)
Metaprogramming
Automating the production of individually
configured systems
Building adaptive systems that need to be
able to dynamically adjust themselves to a
changing environment
Writing programs that represent and
manipulate other programs or themselves
(reflection)
2
![Page 4: C++ Template Metaprogramming - unipi.itdidawiki.cli.di.unipi.it/.../pa/templatemetaprogramming.pdf · C++ as a Two-Level Language Dynamic code is compiled and executed at runtime](https://reader030.vdocuments.site/reader030/viewer/2022041103/5f01bd4a7e708231d400cde7/html5/thumbnails/4.jpg)
Types of System Configuration
Post-Runtime Optimizations
Reflective Systems
Static Typing, Templates, Static Binding, Inlining, Preprocessing, Configuration Management
Dynamic Polymorphism,
State
Static Dynamic
Stat
icD
ynam
ic
Selection of configuration
Cre
atio
n o
f C
om
ponents
and
Configu
rations
3
![Page 5: C++ Template Metaprogramming - unipi.itdidawiki.cli.di.unipi.it/.../pa/templatemetaprogramming.pdf · C++ as a Two-Level Language Dynamic code is compiled and executed at runtime](https://reader030.vdocuments.site/reader030/viewer/2022041103/5f01bd4a7e708231d400cde7/html5/thumbnails/5.jpg)
Metaprograms
Compile time
Post-runtime
Information
for static
analysis only
Linking Loading Runtime Complete
execution
history
Metaprograms
Analysis Generation
4
![Page 6: C++ Template Metaprogramming - unipi.itdidawiki.cli.di.unipi.it/.../pa/templatemetaprogramming.pdf · C++ as a Two-Level Language Dynamic code is compiled and executed at runtime](https://reader030.vdocuments.site/reader030/viewer/2022041103/5f01bd4a7e708231d400cde7/html5/thumbnails/6.jpg)
C++ Support for Configuration
Dynamic Configuration
◦ Dynamic polymorphism (virtual methods)
Static Configuration
◦ Static typing
◦ Static binding
◦ Inlining
◦ Templates
◦ Parameterized inheritance
◦ typedef
◦ Member types and nested classes
5
![Page 7: C++ Template Metaprogramming - unipi.itdidawiki.cli.di.unipi.it/.../pa/templatemetaprogramming.pdf · C++ as a Two-Level Language Dynamic code is compiled and executed at runtime](https://reader030.vdocuments.site/reader030/viewer/2022041103/5f01bd4a7e708231d400cde7/html5/thumbnails/7.jpg)
C++ as a Two-Level Language
Dynamic code is compiled and executed
at runtime
Static code is evaluated at compile time
C++ template together with a number of
other C++ features constitute a Turing-
complete compile-time language!
◦ Looping – template recursion
◦ Conditional – template specialization
6
![Page 8: C++ Template Metaprogramming - unipi.itdidawiki.cli.di.unipi.it/.../pa/templatemetaprogramming.pdf · C++ as a Two-Level Language Dynamic code is compiled and executed at runtime](https://reader030.vdocuments.site/reader030/viewer/2022041103/5f01bd4a7e708231d400cde7/html5/thumbnails/8.jpg)
Example of C++ Static Code
template<int i>
class C {
enum { RET = i };
};
cout << C<2>::RET << endl; // Output 2
int n = 2;
cout << C<n>::RET << endl; // ???
7
![Page 9: C++ Template Metaprogramming - unipi.itdidawiki.cli.di.unipi.it/.../pa/templatemetaprogramming.pdf · C++ as a Two-Level Language Dynamic code is compiled and executed at runtime](https://reader030.vdocuments.site/reader030/viewer/2022041103/5f01bd4a7e708231d400cde7/html5/thumbnails/9.jpg)
Dynamic Factorial Computing
int factorial(int n)
{
return (n == 0) ? 1 : n * factorial(n – 1);
}
cout << factorial(7) << endl; // 5040
8
![Page 10: C++ Template Metaprogramming - unipi.itdidawiki.cli.di.unipi.it/.../pa/templatemetaprogramming.pdf · C++ as a Two-Level Language Dynamic code is compiled and executed at runtime](https://reader030.vdocuments.site/reader030/viewer/2022041103/5f01bd4a7e708231d400cde7/html5/thumbnails/10.jpg)
Static Factorial Computing
template<int n>
struct Fact {
enum { RET = n * Fact<n-1>::RET };
};
template<>
struct Fact<0> {
enum { RET = 1 };
};
cout << Fact<7>::RET << endl; // 5040
int i = 3;
Fact<i>::RET; // ???
9
![Page 11: C++ Template Metaprogramming - unipi.itdidawiki.cli.di.unipi.it/.../pa/templatemetaprogramming.pdf · C++ as a Two-Level Language Dynamic code is compiled and executed at runtime](https://reader030.vdocuments.site/reader030/viewer/2022041103/5f01bd4a7e708231d400cde7/html5/thumbnails/11.jpg)
Dynamic Fibonacci Number
int fibo(long long int n)
{
if (n == 0)
return 0;
if (n == 1)
return 1;
return fibo(n - 1) + fibo(n - 2);
}
cout << fibo(45) << endl;
// 1134903170
// 31.890s with Intel Core 2 Duo 2.4GHz CPU!
10
![Page 12: C++ Template Metaprogramming - unipi.itdidawiki.cli.di.unipi.it/.../pa/templatemetaprogramming.pdf · C++ as a Two-Level Language Dynamic code is compiled and executed at runtime](https://reader030.vdocuments.site/reader030/viewer/2022041103/5f01bd4a7e708231d400cde7/html5/thumbnails/12.jpg)
Static Fibonacci Number
template<long long int n>
struct Fibo {
static const long long int RET =
Fibo<n-1>::RET + Fibo<n-2>::RET;
};
template<>
struct Fibo<0> {
static const long long int RET = 0;
};
template<>
struct Fibo<1> {
static const long long int RET = 1;
};
11
![Page 13: C++ Template Metaprogramming - unipi.itdidawiki.cli.di.unipi.it/.../pa/templatemetaprogramming.pdf · C++ as a Two-Level Language Dynamic code is compiled and executed at runtime](https://reader030.vdocuments.site/reader030/viewer/2022041103/5f01bd4a7e708231d400cde7/html5/thumbnails/13.jpg)
Efficiency of Static Code
long long int x = Fibo<45>::RET;
cout << x << endl;
// 1134903170
// runtime 0.006s
// compile time 0.314s
long long int x = Fibo<500>::RET; // !!!!!
cout << x << endl;
// 2171430676560690477
// runtime 0.005s
// compile time 0.373s
12
![Page 14: C++ Template Metaprogramming - unipi.itdidawiki.cli.di.unipi.it/.../pa/templatemetaprogramming.pdf · C++ as a Two-Level Language Dynamic code is compiled and executed at runtime](https://reader030.vdocuments.site/reader030/viewer/2022041103/5f01bd4a7e708231d400cde7/html5/thumbnails/14.jpg)
Why?
There is no double-recursion in static code!
Compiler sees Fib<7>::RET, it instantiates the
structure template Fib<> for n=7
At this point, the compiler also has to
instantiate Fib<6>::RET and Fib<5>::RET
And then for n=4, n=3, n=2, n=1, and n=0
We can regard Fib<> as a function, which is
evaluated at compile time
The dynamic code only does “<<”!
13
![Page 15: C++ Template Metaprogramming - unipi.itdidawiki.cli.di.unipi.it/.../pa/templatemetaprogramming.pdf · C++ as a Two-Level Language Dynamic code is compiled and executed at runtime](https://reader030.vdocuments.site/reader030/viewer/2022041103/5f01bd4a7e708231d400cde7/html5/thumbnails/15.jpg)
Functional Flavor of Static Level
Class templates as functions
Integers and types as data
Symbolic names instead of variables
Constant initialization and typedef instead
of assignment
Template recursion instead of loops
Conditional operator and template
specialization as conditional construct
14
![Page 16: C++ Template Metaprogramming - unipi.itdidawiki.cli.di.unipi.it/.../pa/templatemetaprogramming.pdf · C++ as a Two-Level Language Dynamic code is compiled and executed at runtime](https://reader030.vdocuments.site/reader030/viewer/2022041103/5f01bd4a7e708231d400cde7/html5/thumbnails/16.jpg)
Template Metaprogramming Map
Metainformation
Metafunctions
Membre
Traits
Traits
Classes
Traits
Templates
Lists and
Trees as
Nested
Templates
Computing Numbers Fibonacci<>
Control Structures
Computing Types IF<>,SWITCH<>,
WHILE<>,DO<>,FOR<>
Computing Code EWHILE<>,EDO<>,
EFOR<>
Expression Templates
15
![Page 17: C++ Template Metaprogramming - unipi.itdidawiki.cli.di.unipi.it/.../pa/templatemetaprogramming.pdf · C++ as a Two-Level Language Dynamic code is compiled and executed at runtime](https://reader030.vdocuments.site/reader030/viewer/2022041103/5f01bd4a7e708231d400cde7/html5/thumbnails/17.jpg)
Member Traits
struct Car {
enum { car, alfaromeo, fiat, peugeot };
enum { id = car};
};
struct AlfaRomeo: Car {
enum { id = alfaromeo };
};
struct Fiat: Car {
enum { id = fiat };
};
struct Peugeot: Car {
enum { id = peugeot };
};
myCar.id == myCar::peugeot; // runtime type test
16
![Page 18: C++ Template Metaprogramming - unipi.itdidawiki.cli.di.unipi.it/.../pa/templatemetaprogramming.pdf · C++ as a Two-Level Language Dynamic code is compiled and executed at runtime](https://reader030.vdocuments.site/reader030/viewer/2022041103/5f01bd4a7e708231d400cde7/html5/thumbnails/18.jpg)
Traits Templates
template<class T>
class car_traits {
public:
enum { MADE, ITALY, FRANCE };
enum { FUEL, DIESEL, PETROL };
static const int made = MADE;
static const int fuel = FUEL;
static const bool trans = 0;
static const char gearbox = 0;
static const char ports = 0;
static const double volume = 0.0;
};
17
![Page 19: C++ Template Metaprogramming - unipi.itdidawiki.cli.di.unipi.it/.../pa/templatemetaprogramming.pdf · C++ as a Two-Level Language Dynamic code is compiled and executed at runtime](https://reader030.vdocuments.site/reader030/viewer/2022041103/5f01bd4a7e708231d400cde7/html5/thumbnails/19.jpg)
Traits Templates: Specialization
template<>
class car_traits<Peugeot> {
public:
enum { MADE, ITALY, FRANCE };
enum { FUEL, DIESEL, PETROL };
static const char made = FRANCE;
static const char fuel = FUEL;
static const char ports = 0;
static const char speeds = 0;
static const double volume = 0.0;
};
18
![Page 20: C++ Template Metaprogramming - unipi.itdidawiki.cli.di.unipi.it/.../pa/templatemetaprogramming.pdf · C++ as a Two-Level Language Dynamic code is compiled and executed at runtime](https://reader030.vdocuments.site/reader030/viewer/2022041103/5f01bd4a7e708231d400cde7/html5/thumbnails/20.jpg)
Traits Templates: Extension
class DieselCar {
public:
enum { FUEL, DIESEL, PETROL };
static const int fuel = DIESEL;
};
template<>
class car_traits<MyCar>: public DieselCar {
static const char ports = 5;
static const char speeds = 5;
static const double volume = 1.9;
};
19
![Page 21: C++ Template Metaprogramming - unipi.itdidawiki.cli.di.unipi.it/.../pa/templatemetaprogramming.pdf · C++ as a Two-Level Language Dynamic code is compiled and executed at runtime](https://reader030.vdocuments.site/reader030/viewer/2022041103/5f01bd4a7e708231d400cde7/html5/thumbnails/21.jpg)
IF<> with Partial Specialization
template<bool condition, class Then, class Else>
struct IF {
typedef Then RET;
};
template<class Then, class Else>
struct IF<false, Then, Else> {
typedef Else RET;
};
IF<(1+2>4), short, int>::RET i; // i is int
20
![Page 22: C++ Template Metaprogramming - unipi.itdidawiki.cli.di.unipi.it/.../pa/templatemetaprogramming.pdf · C++ as a Two-Level Language Dynamic code is compiled and executed at runtime](https://reader030.vdocuments.site/reader030/viewer/2022041103/5f01bd4a7e708231d400cde7/html5/thumbnails/22.jpg)
Usage of IF<> Structure
class DieselMotor: Motor {
public:
virtual void assemble() {}
};
class PetrolMotor: Motor {
public:
virtual void assemble() {}
};
IF<Car::motor == Car::DIESEL,
DieselMotor, PetrolMotor>::RET motor;
motor.assemble();
21
![Page 23: C++ Template Metaprogramming - unipi.itdidawiki.cli.di.unipi.it/.../pa/templatemetaprogramming.pdf · C++ as a Two-Level Language Dynamic code is compiled and executed at runtime](https://reader030.vdocuments.site/reader030/viewer/2022041103/5f01bd4a7e708231d400cde7/html5/thumbnails/23.jpg)
Other Operators
struct FalseType {};
struct TrueType {};
template <class T>
struct isPointer { typedef FalseType RET; };
template <class T>
struct isPointer<T*> {
typedef TrueType RET; };
![Page 24: C++ Template Metaprogramming - unipi.itdidawiki.cli.di.unipi.it/.../pa/templatemetaprogramming.pdf · C++ as a Two-Level Language Dynamic code is compiled and executed at runtime](https://reader030.vdocuments.site/reader030/viewer/2022041103/5f01bd4a7e708231d400cde7/html5/thumbnails/24.jpg)
Conditional
template<int n1, int n2>
struct Max {
enum { RET = (n1 > n2) ? n1 : n2 };
}
![Page 25: C++ Template Metaprogramming - unipi.itdidawiki.cli.di.unipi.it/.../pa/templatemetaprogramming.pdf · C++ as a Two-Level Language Dynamic code is compiled and executed at runtime](https://reader030.vdocuments.site/reader030/viewer/2022041103/5f01bd4a7e708231d400cde7/html5/thumbnails/25.jpg)
Template Metafunctions
C(k, n) = n! / (k! * (n-k)!)
template<int k, int n>
struct Comb {
enum { RET = Fact<n>::RET /
(Fact<k>::RET * Fact<n-k>::RET) };
};
cout << Comb<2, 4>::RET << endl;
![Page 26: C++ Template Metaprogramming - unipi.itdidawiki.cli.di.unipi.it/.../pa/templatemetaprogramming.pdf · C++ as a Two-Level Language Dynamic code is compiled and executed at runtime](https://reader030.vdocuments.site/reader030/viewer/2022041103/5f01bd4a7e708231d400cde7/html5/thumbnails/26.jpg)
Functions on Templates
template <class L>
struct Length {
enum { RET = 1 + Length<L::next>::RET
};
};
template <>
struct Length<Nil> { enum RET = 0 };
![Page 27: C++ Template Metaprogramming - unipi.itdidawiki.cli.di.unipi.it/.../pa/templatemetaprogramming.pdf · C++ as a Two-Level Language Dynamic code is compiled and executed at runtime](https://reader030.vdocuments.site/reader030/viewer/2022041103/5f01bd4a7e708231d400cde7/html5/thumbnails/27.jpg)
Possible Uses
Control loop unrolling:
FOR<3, B>::loop;
![Page 28: C++ Template Metaprogramming - unipi.itdidawiki.cli.di.unipi.it/.../pa/templatemetaprogramming.pdf · C++ as a Two-Level Language Dynamic code is compiled and executed at runtime](https://reader030.vdocuments.site/reader030/viewer/2022041103/5f01bd4a7e708231d400cde7/html5/thumbnails/28.jpg)
Representing Data Structures
template<int n, class Next>
struct List {
enum { item = n };
typedef Next next;
};
struct Nil { };
typedef List<1, List<2, Nil()> > Vector;
V::item == 1;
V::next::item == 2;
V::next::next == Nil;
27
![Page 29: C++ Template Metaprogramming - unipi.itdidawiki.cli.di.unipi.it/.../pa/templatemetaprogramming.pdf · C++ as a Two-Level Language Dynamic code is compiled and executed at runtime](https://reader030.vdocuments.site/reader030/viewer/2022041103/5f01bd4a7e708231d400cde7/html5/thumbnails/29.jpg)
Length of a List
template<class L>
struct Length {
enum { RET = 1 + Length<L::next>::RET };
};
template<>
struct Length<Nil> { enum RET = 0 };
cout << Length<Vector> << endl;
// What’s the length of Vector?
28
![Page 30: C++ Template Metaprogramming - unipi.itdidawiki.cli.di.unipi.it/.../pa/templatemetaprogramming.pdf · C++ as a Two-Level Language Dynamic code is compiled and executed at runtime](https://reader030.vdocuments.site/reader030/viewer/2022041103/5f01bd4a7e708231d400cde7/html5/thumbnails/30.jpg)
Unrolling Vector Addition
void add(size_t size, int* a, int* b, int* c)
{
while (size--)
*c++ = *a++ + *b++;
}
29
![Page 31: C++ Template Metaprogramming - unipi.itdidawiki.cli.di.unipi.it/.../pa/templatemetaprogramming.pdf · C++ as a Two-Level Language Dynamic code is compiled and executed at runtime](https://reader030.vdocuments.site/reader030/viewer/2022041103/5f01bd4a7e708231d400cde7/html5/thumbnails/31.jpg)
Template Unrolling
template<int size>
inline void add(int* a, int* b, int* c)
{
*c = *a + *b;
add<size-1>(a + 1, b + 1, c + 1);
}
template<>
inline void add<0>(int* a, int* b, int* c) { }
add<3>(a, b, c);
30
![Page 32: C++ Template Metaprogramming - unipi.itdidawiki.cli.di.unipi.it/.../pa/templatemetaprogramming.pdf · C++ as a Two-Level Language Dynamic code is compiled and executed at runtime](https://reader030.vdocuments.site/reader030/viewer/2022041103/5f01bd4a7e708231d400cde7/html5/thumbnails/32.jpg)
Effect of Unrolling
add<3>(a, b, c);
*c = *a + *b;
add<2>(a + 1, b + 1, c + 1);
*(c + 1) = *(a + 1) + *(b + 1);
add<1>(a + 2, b + 2, c + 2);
*(c + 2) = *(a + 2) + *(b + 2);
add<0>(a + 3, b + 3, c + 3);
31
![Page 33: C++ Template Metaprogramming - unipi.itdidawiki.cli.di.unipi.it/.../pa/templatemetaprogramming.pdf · C++ as a Two-Level Language Dynamic code is compiled and executed at runtime](https://reader030.vdocuments.site/reader030/viewer/2022041103/5f01bd4a7e708231d400cde7/html5/thumbnails/33.jpg)
For-Loop
template<int n, class B>
struct FOR {
static void loop(int n) {
UNROLL<n, B>::iteration(0);
}
};
32
![Page 34: C++ Template Metaprogramming - unipi.itdidawiki.cli.di.unipi.it/.../pa/templatemetaprogramming.pdf · C++ as a Two-Level Language Dynamic code is compiled and executed at runtime](https://reader030.vdocuments.site/reader030/viewer/2022041103/5f01bd4a7e708231d400cde7/html5/thumbnails/34.jpg)
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) { }
};
33
![Page 35: C++ Template Metaprogramming - unipi.itdidawiki.cli.di.unipi.it/.../pa/templatemetaprogramming.pdf · C++ as a Two-Level Language Dynamic code is compiled and executed at runtime](https://reader030.vdocuments.site/reader030/viewer/2022041103/5f01bd4a7e708231d400cde7/html5/thumbnails/35.jpg)
Loop Unrolling (2)
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) { }
};
![Page 36: C++ Template Metaprogramming - unipi.itdidawiki.cli.di.unipi.it/.../pa/templatemetaprogramming.pdf · C++ as a Two-Level Language Dynamic code is compiled and executed at runtime](https://reader030.vdocuments.site/reader030/viewer/2022041103/5f01bd4a7e708231d400cde7/html5/thumbnails/36.jpg)
Uses
Blitz++
Boost
35
![Page 37: C++ Template Metaprogramming - unipi.itdidawiki.cli.di.unipi.it/.../pa/templatemetaprogramming.pdf · C++ as a Two-Level Language Dynamic code is compiled and executed at runtime](https://reader030.vdocuments.site/reader030/viewer/2022041103/5f01bd4a7e708231d400cde7/html5/thumbnails/37.jpg)
Blitz++
A library for algebraic numeric computing
Heavy use of template metaprogramming
Allows achieving faster speed than
dedicated Fortan numeric libraries
36
![Page 38: C++ Template Metaprogramming - unipi.itdidawiki.cli.di.unipi.it/.../pa/templatemetaprogramming.pdf · C++ as a Two-Level Language Dynamic code is compiled and executed at runtime](https://reader030.vdocuments.site/reader030/viewer/2022041103/5f01bd4a7e708231d400cde7/html5/thumbnails/38.jpg)
Boost
General C++ Class Library
Many Uses of template
metaprogrammming:
◦ foreach construct, uses TMP to determie
types of elements on which to iterate,
distinguishes between constant and normal
iterator types
◦ Ublast: library of algebraic linear algebra
(vector, matrix) uses TMP to optimize code
for compound algebraic operations
37
![Page 39: C++ Template Metaprogramming - unipi.itdidawiki.cli.di.unipi.it/.../pa/templatemetaprogramming.pdf · C++ as a Two-Level Language Dynamic code is compiled and executed at runtime](https://reader030.vdocuments.site/reader030/viewer/2022041103/5f01bd4a7e708231d400cde7/html5/thumbnails/39.jpg)
Problems
Readability
Debugging
Error reporting
Compilation time
Compiler limits
Expression templates limits
Portability
38