Читаем Thinking In C++. Volume 2: Practical Programming полностью

To motivate the need for expression templates, consider typical numerical linear algebra operations, such as adding together two matrices or vectors,[75] such as in the following:

D = A + B + C;

In naive implementations, this expression would result in a number of temporaries—one for A+B, and one for (A+B)+C. When these variables represent immense matrices or vectors, the coincident drain on resources is unacceptable. Expression templates allow you to use the same expression without temporaries.

In the following sample program, we define a MyVector class to simulate mathematical vectors of any size. We use a non-type template argument for the length of the vector. We also define a MyVectorSum class to act as a proxy class for a sum of MyVector objects. This allows us to use lazy evaluation, so the addition of vector components is performed on demand without the need for temporaries.

//: C05:MyVector.cpp

// Optimizes away temporaries via templates

#include

#include

#include

using namespace std;

// A proxy class for sums of vectors

template class MyVectorSum;

template

class MyVector {

  T data[N];

public:

  MyVector& operator=(const MyVector& right) {

    for (size_t i = 0; i < N; ++i)

      data[i] = right.data[i];

    return *this;

  }

  MyVector& operator=(const MyVectorSum& right);

  const T& operator[](size_t i) const {

    return data[i];

  }

  T& operator[](size_t i) {

    return data[i];

  }

};

// Proxy class hold references; uses lazy addition

template

class MyVectorSum {

  const MyVector& left;

  const MyVector& right;

public:

  MyVectorSum(const MyVector& lhs,

              const MyVector& rhs)

      : left(lhs), right(rhs) {}

  T operator[](size_t i) const {

    return left[i] + right[i];

  }

};

// Operator to support v3 = v1 + v2

template

MyVector&

MyVector::operator=(const MyVectorSum& right) {

  for (size_t i = 0; i < N; ++i)

    data[i] = right[i];

  return *this;

}

// operator+ just stores references

template

inline MyVectorSum

operator+(const MyVector& left,

          const MyVector& right) {

  return MyVectorSum(left, right);

}

// Convenience functions for the test program below

template

void init(MyVector& v) {

  for (size_t i = 0; i < N; ++i)

    v[i] = rand() % 100;

}

template

void print(MyVector& v) {

  for (size_t i = 0; i < N; ++i)

    cout << v[i] << ' ';

  cout << endl;

}

int main() {

  MyVector v1;

  init(v1);

  print(v1);

  MyVector v2;

  init(v2);

  print(v2);

  MyVector v3;

  v3 = v1 + v2;

  print(v3);

  MyVector v4;

  // Not yet supported:

//!  v4 = v1 + v2 + v3;

} ///:~.

The MyVectorSum class does no computation when it is created; it merely holds references to the two vectors to be added. It is only when you access a component of a vector sum that it is calculated (see its operator[]( )). The overload of the assignment operator for MyVector that takes a MyVectorSum argument is for an expression such as:.

v1 = v2 + v3;  // add two vectors

When the expression v1+v2 is evaluated, a MyVectorSum object is returned (or actually, inserted inline, since that operator+( ) is declared inline). This is a small, fixed-size object (it holds only two references). Then the assignment operator mentioned above is invoked:

v3.operator=(MyVectorSum(v2, v3));

This assigns to each element of v3 the sum of the corresponding elements of v1 and v2, computed in real time. No temporary MyVector objects are created.

This program does not support an expression that has more than two operands, however, such as

v4 = v1 + v2 + v3;

The reason is that after the first addition, a second addition is attempted:

(v1 + v2) + v3;

which would require an operator+( ) with a first argument of MyVectorSum and a second argument of type MyVector. We could attempt to provide a number of overloads to meet all situations, but it is better to let templates do the work, as in the following version of the program.

//: C05:MyVector2.cpp

// Handles sums of any length with expression templates

#include

#include

#include

using namespace std;

// A proxy class for sums of vectors

template class MyVectorSum;

template

class MyVector {

  T data[N];

public:

  MyVector& operator=(const MyVector& right) {

    for (size_t i = 0; i < N; ++i)

      data[i] = right.data[i];

    return *this;

  }

  template

  MyVector&

    operator=(const MyVectorSum& right);

  const T& operator[](size_t i) const {

    return data[i];

  }

  T& operator[](size_t i) {

    return data[i];

  }

};

// Allows mixing MyVector and MyVectorSum

template

class MyVectorSum {

  const Left& left;

  const Right& right;

public:

  MyVectorSum(const Left& lhs, const Right& rhs)

      : left(lhs), right(rhs) {}

  T operator[](size_t i) const {

    return left[i] + right[i];

  }

};

template

template

MyVector&

MyVector::

operator=(const MyVectorSum& right) {

  for (size_t i = 0; i < N; ++i)

    data[i] = right[i];

  return *this;

}

// operator+ just stores references

template

Перейти на страницу:

Похожие книги

3ds Max 2008
3ds Max 2008

Одни уверены, что нет лучшего способа обучения 3ds Мах, чем прочитать хорошую книгу. Другие склоняются к тому, что эффективнее учиться у преподавателя, который показывает, что и как нужно делать. Данное издание объединяет оба подхода. Его цель – сделать освоение 3ds Мах 2008 максимально быстрым и результативным. Часто после изучения книги у читателя возникают вопросы, почему не получился тот или иной пример. Видеокурс – это гарантия, что такие вопросы не возникнут: ведь автор не только рассказывает, но и показывает, как нужно работать в 3ds Мах.В отличие от большинства интерактивных курсов, где работа в 3ds Мах иллюстрируется на кубиках-шариках, данный видеокурс полностью практический. Все приемы работы с инструментами 3ds Мах 2008 показаны на конкретных примерах, благодаря чему после просмотра курса читатель сможет самостоятельно выполнять даже сложные проекты.

Владимир Антонович Верстак , Владимир Верстак

Программирование, программы, базы данных / Программное обеспечение / Книги по IT