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

The "template<>" prefix tells the compiler that what follows is a specialization of a template. The type for the specialization must appear in angle brackets immediately following the function name, as it normally would in an explicitly-specified call. Note that we carefully substitute const char* for T in the explicit specialization. Whenever the original template specifies const T, that const modifies the whole type T. It is the pointer to a const char* that is const. Therefore we must write const char* const in place of const T in the specialization. When the compiler sees a call to min with const char* arguments in the program, it will instantiate our const char* version of min so it can be called. The two calls to min in this program call the same specialization of min.

Explicit specializations tend to be more useful for class templates than for function templates. When you provide a full specialization for a class template, though, you may need to implement all the member functions. This is because you are providing a separate class, and client code may expect the complete interface to be implemented.

The standard library has an explicit specialization for vector when it is used to hold objects of type bool. As you saw earlier in this chapter, the declaration for the primary vector class template is:

template >

class vector {…};

To specialize for objects of type bool, you could declare an explicit specialization as follows:

template <>

class vector< bool, allocator > {…};

Again, this is quickly recognized as a full, explicit specialization because of the template<> prefix and because all the primary template’s parameters are satisfied by the argument list appended to the class name. The purpose for vector is to allow library implementations to save space by packing bits into integers.[58] 

It turns out that vector is a little more flexible than we have described, as seen in the next section.

<p>Partial Specialization</p>

Class templates can also be partially specialized, meaning that at least one of the template parameters is left "open" in some way in the specialization. This is actually what vector does; it specifies the object type (bool), but leaves the allocator type unspecified. Here is the actual declaration of vector:

template

class vector;

You can recognize a partial specialization because non-empty parameter lists appear in angle brackets both after the template keyword (the unspecified parameters) and after the class (the specified arguments). Because of the way vector is defined, a user can provide a custom allocator type, even though the contained type of bool is fixed. In other words, specialization, and partial specialization in particular, constitute a sort of "overloading" for class templates.

<p>Partial ordering of class templates</p>

The rules that determine which template is selected for instantiation are similar to the partial ordering for function templates—the "most specialized" template is selected. An illustration follows. (The string in each f( ) member function below explains the role of each template definition.).

//: C05:PartialOrder2.cpp

// Reveals partial ordering of class templates

#include

using namespace std;

template class C {

public:

  void f() {

    cout << "Primary Template\n";

  }

};

template class C {

public:

  void f() {

    cout << "T == int\n";

  }

};

template class C {

public:

  void f() {

    cout << "U == double\n";

  }

};

template class C {

public:

  void f() {

    cout << "T* used \n";

  }

};

template class C {

public:

  void f() {

    cout << "U* used\n";

  }

};

template class C {

public:

  void f() {

    cout << "T* and U* used\n";

  }

};

template class C {

public:

  void f() {

    cout << "T == U\n";

  }

};

int main() {

  C().f();    // 1: Primary template

  C().f();    // 2: T == int

  C().f(); // 3: U == double

  C().f();  // 4: T == U

  C().f(); // 5: T* used [T is float]

  C().f(); // 6: U* used [U is float]

  C().f();  // 7: T* and U* used [float,int]

  // The following are ambiguous:

//   8: C().f();

//   9: C().f();

//  10: C().f();

//  11: C().f();

//  12: C().f();

} ///:~

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

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

3ds Max 2008
3ds Max 2008

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

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

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