C++ is a statically typed, free-form, multi-paradigm, compiled, general-purpose programming language. It is regarded as an intermediate-level language, as it comprises a combination of both high-level and low-level language features. It was developed by Bjarne Stroustrup starting in 1979 at Bell...
Template metaprogramming is a metaprogramming technique in which templates are used by a compiler to generate temporary source code, which is merged by the compiler with the rest of the source code and then compiled. The output of these templates include compile-time constants, data structures, and...
In a broad definition, generic programming is a style of computer programming in which algorithms are written in terms of to-be-specified-later types that are then instantiated when needed for specific types provided as parameters...
are used to represent part of an expression. Typically, the template itself represents a particular type of operation, while the parameters represent the operands to which the operation applies. The expression template can then be evaluated
Lazy evaluation
In programming language theory, lazy evaluation or call-by-need is an evaluation strategy which delays the evaluation of an expression until the value of this is actually required and which also avoids repeated evaluations...
at a later time, or passed to a function. The technique was proposed by Todd Veldhuizen in his June 1995 article in the C++ Report
C++ Report
C++ Report was a bi-monthly professional computer magazine published by SIGS Publications Group. It has been edited by Stanley B. Lippman, Douglas C. Schmidt, Brad Appleton and Robert Cecil Martin and aimed to cover various issues related to C++ programming language. It has been widely recognized...
.
For example, consider a library representing vectors with a class Vec. It is natural to want to overload operator- and operator* so you could write Vec x = alpha*(u - v); where alpha is a scalar and u and v are Vecs. A naive implementation would have operator- and operator* return Vecs. However, then the above expression would mean creating a temporary for u-v then another temporary for alpha times that first temporary, then assigning that to x.
Expression templates delay evaluation so the expression Vec x = alpha*(u-v); essentially generates at compile time a new Vec constructor taking a scalar and two Vecs as follows (using the curiously recurring template pattern
Curiously Recurring Template Pattern
The curiously recurring template pattern is a C++ idiom in which a class X derives from a class template instantiation using X itself as template argument...
as is used by Boost.uBLAS):
include
include
template
// A CRTP base class for Vecs with a size and indexing:
class VecExpression {
public:
typedef std::vector container_type;
typedef container_type::size_type size_type;
typedef container_type::value_type value_type;
typedef container_type::reference reference;
// The actual Vec class:
class Vec : public VecExpression {
container_type _data;
public:
reference operator[](size_type i) { return _data[i]; }
value_type operator[](size_type i) const { return _data[i]; }
size_type size const { return _data.size; }
Vec(size_type n) : _data(n) {} // Construct a given size:
// Construct from any VecExpression:
template
Vec(VecExpression const& vec) {
E const& v = vec;
_data.resize(v.size);
for (size_type i = 0; i != v.size; ++i) {
_data[i] = v[i];
}
}
};
With the above definitions, the expression alpha*(u-v) is of type VecScaled >
so calling Vec x = alpha * (u-v) calls the constructor that takes a VecExpression > >. Each line of the for loop then expands from
_data[i] = v[i];
to essentially
_data[i] = alpha * (u[i] - v[i]);
with no temporaries needed and only one pass through each memory block.
The source of this article is wikipedia, the free encyclopedia. The text of this article is licensed under the GFDL.