С++ для начинающих




Разрешение имен в определениях шаблонов * - часть 5


// ...

int main() {

   // ...

   // использование min(SmallInt*,int)

   min( &asi[0], size );

}

// точка конкретизации min(SmallInt*,int)

// как будто объявление конкретизированной функции выглядит так:

SmallInt min( SmallInt* array, int size )

   { /* ... */ }

Но что, если конкретизация шаблона случается в одном исходном файле несколько раз? Где тогда будет точка конкретизации? Вы можете спросить: “А какая, собственно, разница?” В нашем примере для SmallInt разница есть, поскольку объявление функции print(const SmallInt &) должно появиться перед точкой конкретизации min(SmallInt*,int):

#include <primer.h>

void another();

SmallInt asi[4];

int main() {

   // задать значения элементов массива asi

   int size = sizeof(asi) / sizeof(SmallInt);

   min( &asi[0], size );

   another();

   // ...

}

// точка конкретизации здесь?

void another() {

   int size = sizeof(asi) / sizeof(SmallInt);

   min( &asi[0], size );

}

// или здесь?

В действительности точка конкретизации находится после определения каждой функции, в которой используется конкретизированный экземпляр. Компилятор может выбрать любую из этих точек, чтобы конкретизировать в ней шаблон. Отсюда следует, что при организации кода программы надо быть внимательным и помещать все объявления, необходимые для разрешения имен, зависящих от параметров некоторого шаблона, перед первой точкой. Поэтому разумно поместить их в заголовочный файл, который включается перед любой возможной конкретизацией шаблона:

#include <primer.h>

// user.h содержит объявления, необходимые при конкретизации

#include "user.h"

void another();

SmallInt asi[4];

int main() {

   // ...

}

// первая точка конкретизации min(SmallInt*,int)

void another() {

   // ...

}

// вторая точка конкретизации min(SmallInt*,int)

А если конкретизация шаблона происходит в нескольких файлах? Например, что будет, если функция another() находится в другом файле, нежели main()? Тогда точка конкретизации есть в каждом файле, где используется конкретизированная из шаблона функция. Компилятор свободен в выборе любой из них, так что нам снова придется проявить аккуратность и включить файл "user.h" во все исходные файлы, где используются конкретизированные функции. Тем самым гарантируется, что реализация min(SmallInt*,int) будет ссылаться именно на нашу функцию print(const SmallInt &) вне зависимости от того, какую из точек конкретизации выберет компилятор.




Содержание  Назад  Вперед