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

A drawback of this approach is obviously that all template source code is visible to the client. If you want to know exactly how your standard library is implemented, all you have to do is inspect the headers in your installation. There is little opportunity for library vendors to hide their implementation strategies. Another noticeable disadvantage of the inclusion model is that header files are much, much larger than they would be if function bodies were compiled separately. This can increase compile times dramatically over traditional compilation models.

To help reduce the large headers required by the inclusion model, C++ offers two (non-exclusive) alternative code organization mechanisms: you can manually instantiate each specialization using explicit instantiation or you can use exported templates, which actually support a large degree of separate compilation.

<p>Explicit instantiation</p>

You can manually direct the compiler to instantiate any template specializations of your choice. When you use this technique, there must be one and only one such directive for each such specialization; otherwise you might get multiple definition errors, just as you would with ordinary, non-inline functions with identical signatures. To illustrate, we first (erroneously) separate the declaration of the min template from earlier in this chapter from its definition, following the normal pattern for ordinary, non-inline functions. The following example consists of five files:.

·         OurMin.h: contains the declaration of the min function template.

·         OurMin.cpp: contains the definition of the min function template.

·         UseMin1.cpp: attempts to use an int-instantiation of min

·         UseMin2.cpp: attempts to use a double-instantiation of min

·         MinMain.cpp: calls usemin1( ) and usemin2( )

Here are the files:

//: C05:OurMin.h

#ifndef OURMIN_H

#define OURMIN_H

// The declaration of min

template const T& min(const T&, const T&);

#endif ///:~

// OurMin.cpp

#include "OurMin.h"

// The definition of min

template const T& min(const T& a, const T& b) {

  return (a < b) ? a : b;

}

//: C05:UseMin1.cpp {O}

#include

#include "OurMin.h"

void usemin1() {

  std::cout << min(1,2) << std::endl;

} ///:~

//: C05:UseMin2.cpp {O}

#include

#include "OurMin.h"

void usemin2() {

  std::cout << min(3.1,4.2) << std::endl;

} ///:~

//: C05:MinMain.cpp

//{L} UseMin1 UseMin2 MinInstances

void usemin1();

void usemin2();

int main() {

  usemin1();

  usemin2();

} ///:~

When we attempt to build this program, the linker reports unresolved external references for min( ) and min( ). The reason is that when the compiler encounters the calls to specializations of min in UseMin1 and UseMin2, only the declaration of min is visible. Since the definition is not available, the compiler assumes it will come from some other translation unit, and the needed specializations are therefore not instantiated at that point, leaving the linker to eventually complain that it cannot find them.

To solve this problem, we will introduce a new file, MinInstances.cpp, that explicitly instantiates the needed specializations of min:

//: C05:MinInstances.cpp {O}

#include "OurMin.cpp"

// Explicit Instantiations for int and double

template const int& min(const int&, const int&);

template const double& min(const double&,

                    const double&);

///:~

To manually instantiate a particular template specialization, you precede the specialization’s declaration with the template keyword. That’s it! Note that we must include OurMin.cpp, not OurMin.h, here, because the compiler needs the template definition to perform the instantiation. This is the only place where we have to do this in this program,[77] however, since it gives us the unique instantiations of min that we need; the declarations alone suffice for the other files. Since we are including OurMin.cpp with the macro preprocessor, we add include guards:.

//: C05:OurMin.cpp {O}

#ifndef OURMIN_CPP

#define OURMIN_CPP

#include "OurMin.h"

template const T& min(const T& a, const T& b) {

  return (a < b) ? a : b;

}

#endif ///:~

Now when we compile all the files together into a complete program, the unique instances of min are found, and the program executes correctly, giving the output:

1

3.1

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

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

3ds Max 2008
3ds Max 2008

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

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

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