Читаем 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

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

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

1С: Бухгалтерия 8 с нуля
1С: Бухгалтерия 8 с нуля

Книга содержит полное описание приемов и методов работы с программой 1С:Бухгалтерия 8. Рассматривается автоматизация всех основных участков бухгалтерии: учет наличных и безналичных денежных средств, основных средств и НМА, прихода и расхода товарно-материальных ценностей, зарплаты, производства. Описано, как вводить исходные данные, заполнять справочники и каталоги, работать с первичными документами, проводить их по учету, формировать разнообразные отчеты, выводить данные на печать, настраивать программу и использовать ее сервисные функции. Каждый урок содержит подробное описание рассматриваемой темы с детальным разбором и иллюстрированием всех этапов.Для широкого круга пользователей.

Алексей Анатольевич Гладкий

Программирование, программы, базы данных / Программное обеспечение / Бухучет и аудит / Финансы и бизнес / Книги по IT / Словари и Энциклопедии
1С: Управление торговлей 8.2
1С: Управление торговлей 8.2

Современные торговые предприятия предлагают своим клиентам широчайший ассортимент товаров, который исчисляется тысячами и десятками тысяч наименований. Причем многие позиции могут реализовываться на разных условиях: предоплата, отсрочка платежи, скидка, наценка, объем партии, и т.д. Клиенты зачастую делятся на категории – VIP-клиент, обычный клиент, постоянный клиент, мелкооптовый клиент, и т.д. Товарные позиции могут комплектоваться и разукомплектовываться, многие товары подлежат обязательной сертификации и гигиеническим исследованиям, некондиционные позиции необходимо списывать, на складах периодически должна проводиться инвентаризация, каждая компания должна иметь свою маркетинговую политику и т.д., вообщем – современное торговое предприятие представляет живой организм, находящийся в постоянном движении.Очевидно, что вся эта кипучая деятельность требует автоматизации. Для решения этой задачи существуют специальные программные средства, и в этой книге мы познакомим вам с самым популярным продуктом, предназначенным для автоматизации деятельности торгового предприятия – «1С Управление торговлей», которое реализовано на новейшей технологической платформе версии 1С 8.2.

Алексей Анатольевич Гладкий

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