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

Without understanding the likes of the previous examples in this section, novices find themselves frustrated because they can’t get a simple stream output inserter to work. If you don’t define your operators inside the definition of Box, you must provide the forward declarations we showed earlier:.

//: C05:Box1.cpp

// Defines template operators

#include

using namespace std;

// Forward declarations

template

class Box;

template

Box operator+(const Box&, const Box&);

template

ostream& operator<<(ostream&, const Box&);

template

class Box {

  T t;

public:

  Box(const T& theT) : t(theT) {}

  friend Box operator+<>(const Box&, const Box&);

  friend ostream& operator<< <>(ostream&, const Box&);

};

template

Box operator+(const Box& b1, const Box& b2) {

  return Box(b1.t + b2.t);

}

template

ostream& operator<<(ostream& os, const Box& b) {

  return os << '[' << b.t << ']';

}

int main() {

  Box b1(1), b2(2);

  cout << b1 + b2 << endl;  // [3]

//  cout << b1 + 2 << endl; // no implicit conversions!

} ///:~

Here we are defining both an addition operator and an output stream operator. The main program reveals a disadvantage of this approach: you can’t depend on implicit conversions (see the expression b1 + 2) because templates do not provide them. Using the in-class, non-template approach is shorter and more robust:.

//: C05:Box2.cpp

// Defines non-template operators

#include

using namespace std;

template

class Box {

  T t;

public:

  Box(const T& theT) : t(theT) {}

  friend Box operator+(const Box& b1,

          const Box& b2) {

    return Box(b1.t + b2.t);

  }

  friend ostream& operator<<(ostream& os,

                const Box& b) {

    return os << '[' << b.t << ']';

  }

};

int main() {

  Box b1(1), b2(2);

  cout << b1 + b2 << endl;  // [3]

  cout << b1 + 2 << endl;   // [3]

} ///:~

Because the operators are normal functions (overloaded for each specialization of Box—just int in this case, of course), implicit conversions are applied as normal; so the expression b1 + 2 is valid.

<p>Friend templates</p>

You can be precise as to which specializations of a template are friends of a class. In the examples in the previous section, only the specialization of the function template f with the same type that specialized Friendly was a friend. For example, only the specialization f(const Friendly&) is a friend of the class Friendly. This was accomplished by using the template parameter for Friendly to specialize f in its friend declaration. If we had wanted to, we could have made a particular, fixed specialization of f a friend to all instances of Friendly, like this:.

// Inside Friendly:

  friend void f<>(const Friendly&);

By using double instead of T, the double specialization of f has access to the non-public members of any Friendly specialization. The specialization f( ) still isn’t instantiated unless it is explicitly called, of course.

Likewise, if you were to declare a non-template function with no parameters dependent on T, that single function would be a friend to all instances of Friendly:.

// Inside of Friendly:

  friend void g(int);  // g(int) befriends all Friendly’s

As always, since g(int) is unqualified, it must be defined at file scope (the namespace scope containing Friendly).

It is also possible to arrange for all specializations of f to be friends for all specializations of Friendly, with a so-called friend template, as follows:

template

class Friendly {

  template friend void f<>(const Friendly&);

Since the template argument for the friend declaration is independent of T, any combination of T and U is allowed, achieving the friendship objective. Like member templates, friend templates can appear within non-template classes as well.

<p>Template programming idioms</p>

Since language is a tool of thought, new language features tend to spawn new programming techniques. In this section we cover some commonly-used template programming idioms that have emerged in the years since templates were added to the C++ language.[62] 

<p>Traits</p>

The traits template technique, pioneered by Nathan Myers, is a means of bundling type-dependent declarations together. In essence, using traits allows you to "mix and match" certain types and values with contexts that use them in a flexible manner, while keeping your code readable and maintainable.

The simplest example of a traits template is the numeric_limits class template defined in . The primary template is defined as follows:

template class numeric_limits {

public:

  static const bool is_specialized = false;

  static T min() throw();

  static T max() throw();

  static const int digits = 0;

  static const int digits10 = 0;

  static const bool is_signed = false;

  static const bool is_integer = false;

  static const bool is_exact = false;

  static const int radix = 0;

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

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

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

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

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

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

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

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

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