03.12.2012 Views

C++ for Scientists - Technische Universität Dresden

C++ for Scientists - Technische Universität Dresden

C++ for Scientists - Technische Universität Dresden

SHOW MORE
SHOW LESS

Create successful ePaper yourself

Turn your PDF publications into a flip-book with our unique Google optimized e-Paper software.

5.3. EXPRESSION TEMPLATES 153<br />

caches of the plat<strong>for</strong>m and the vectors must really be transfer to and from main memory. In<br />

case of shorter vectors, the data might reside in L1 or L2 cache and the data transfer is less<br />

critical. But in this case, the allocation and deallocation becomes a serious slow down factor.<br />

The purpose of expression templates is to keep the original operator notation without introducing<br />

the overhead induced by temporaries.<br />

5.3.2 An Expression Template Class<br />

The solution is to introduce a special class that keeps references to the vectors and allows us<br />

to per<strong>for</strong>m all computations later in one sweep. The addition does not return now a vector but<br />

an object with the references:<br />

template <br />

class vector sum<br />

{<br />

public:<br />

vector sum(const vector& v1, const vector& v2) : v1(v1), v2(v2) {}<br />

private:<br />

const vector& v1, v2;<br />

};<br />

template <br />

vector sum inline operator+(const vector& x, const vector& y)<br />

{<br />

return vector sum(x, y);<br />

}<br />

Now we can already write x + y but not w= x + y yet. It is not only that the assignment is not<br />

defined, we have not yet provided vector sum with enough functionality to per<strong>for</strong>m something<br />

useful in the assignment. Thus, we first extend vector sum so that it looks like a vector itself:<br />

template <br />

class vector sum<br />

{<br />

void check index(int i) const { assert(i >= 0 && i < size(v1)); }<br />

public:<br />

vector sum(const vector& v1, const vector& v2) : v1(v1), v2(v2)<br />

{<br />

assert(size(v1) == size(v2));<br />

}<br />

friend int size(const vector sum& x) { return size(x.v1); }<br />

T operator[](int i) const { check index(i); return v1[i] + v2[i]; }<br />

private:<br />

const vector& v1, v2;<br />

};<br />

For the sake of defensive programming, we added a test that the two vectors have the same<br />

size and can be consistently added. Then we consider the size of the first vector as the size of<br />

our vector sum. The most important function is the bracket operator: when the i th entry we<br />

compute the sum of the operands i th entries.

Hooray! Your file is uploaded and ready to be published.

Saved successfully!

Ooh no, something went wrong!