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

Because the value of N is known at compile time, the underlying array (data) can be placed on the runtime stack instead of on the free store, which can improve runtime performance by avoiding the overhead associated with dynamic memory allocation. Following the pattern mentioned earlier, the name of the class above is Stack. This means that each distinct value of N results in a unique class type. For example, Stack is a distinct class from Stack.

The bitset class template, discussed in detail in Chapter 7, is the only class in the standard C++ library that uses a non-type template parameter, which happens to specify the number of bits the bitset object can hold. The following random number generator example uses a bitset to track numbers so all the numbers in its range are returned in random order without repetition before starting over. This example also overloads operator( ) to produce a familiar function-call syntax.

//: C05:Urand.h

//{-bor}

// Unique randomizer

#ifndef URAND_H

#define URAND_H

#include

#include

#include

#include

using std::size_t;

using std::bitset;

template

class Urand {

  bitset used;

public:

  Urand() {

    srand(time(0));  // randomize

  }

  size_t operator()(); // The "generator" function

};

template

inline size_t Urand::operator()() {

  if(used.count() == UpperBound)

    used.reset();  // start over (clear bitset)

  size_t newval;

  while(used[newval = rand() % UpperBound])

    ; // Until unique value is found

  used[newval] = true;

  return newval;

}

#endif // URAND_H ///:~

The uniqueness of Urand is produced by tracking with a bitset all the numbers possible in the random space (the upper bound is set with the template argument) and by recording each number as it’s used by setting the corresponding position bit in used. When the numbers are all used up, the bitset is cleared to start over. Here’s a simple driver that illustrates how to use a Urand object:.

//: C05:UrandTest.cpp

//{-bor}

#include

#include "Urand.h"

using namespace std;

int main() {

  Urand<10> u;

  for(int i = 0; i < 20; ++i)

    cout << u() << ' ';

} ///:~

As we explain later in this chapter, non-type template arguments are also important in the optimization of numeric computations.

<p>Default template arguments</p>

You can provide default arguments for template parameters in class templates. (They are not allowed in function templates.) As with default function arguments, they should only be defined once, the first time a template declaration or definition is seen by the compiler; and once you introduce a default argument, all the subsequent template parameters must also have defaults. To make the fixed-size Stack template shown earlier a little friendlier, for example, you can add a default argument like this:.

template

class Stack {

  T data[N];  // Fixed capacity is N

  size_t count;

public:

  void push(const T& t);

  // etc.

};

Now, if you omit the second template argument when declaring a Stack object, the value for N will default to 100.

You can choose to provide defaults for all arguments, but you must use an empty set of brackets when declaring an instance so that the compiler knows that a class template is involved. Here’s how:

template  // Both defaulted

class Stack {

  T data[N];  // Fixed capacity is N

  size_t count;

public:

  void push(const T& t);

  // etc.

};

Stack<> myStack;  // Same as Stack.

Default arguments are used heavily in the standard C++ library. The vector class template, for instance, is declared as follows:

template >

class vector;

Note the space between the last two right angle bracket characters. This prevents the compiler from interpreting those two characters (>>) as the right-shift operator.

This declaration reveals that vector actually takes two arguments: the type of the contained objects it holds, and a type that represents the allocator used by the vector. (We talk more about allocators in Chapter 7.) Whenever you omit the second argument, the standard allocator template is used, parameterized by the first template parameter. This declaration also shows that you can use template parameters in other, subsequent template parameters, as T is used here.

Although you cannot use default template arguments in function templates, you can use template parameters as default arguments to normal functions. The following function template adds the elements in a sequence.

//: C05:FuncDef.cpp

#include

using namespace std;

template

T sum(T* b, T* e, T init = T()) {

  while(b != e)

    init += *b++;

  return init;

}

int main() {

  int a[] = {1,2,3};

  cout << sum(a, a+sizeof a / sizeof a[0]) << endl; // 6

} ///:~

The third argument to sum( ) is the initial value for the accumulation of the elements. Since we omitted it, this argument defaults to T( ), which in the case of int and other built-in types invokes a pseudo-constructor that performs zero-initialization.

<p>Template template parameters</p>
Перейти на страницу:

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

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

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

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

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

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

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

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