Когда бы вы использовали шаблон явной реализации?

Я только что прочитал о явной реализации шаблона:

template struct MyStruct<long>;

Он был описан как «довольно редкий», поэтому при каких обстоятельствах это будет полезно?

19

Решение

Одним из вариантов использования является скрытие определений от конечного пользователя.

tpl.h:

template<typename T>
void func(); // Declaration

tpl.cpp:

template<typename T>
void func()
{
// Definition
}

template void func<int>(); // explicit instantiation for int
template void func<double>();  // explicit instantiation for double

main.cpp

#include "tpl.h"int main()
{
func<double>(); // OK
func<int>(); // OK
// func<char>(); - Linking ERROR
}
12

Другие решения

Явное создание экземпляров предназначено для оптимизации использования библиотек шаблонов, предоставляя некоторые (в основном используемые) экземпляры шаблонов в скомпилированной двоичной форме вместо формы исходного кода. Это сократит время компиляции и соединения для приложений конечного пользователя. Например. std::basic_string<char> а также std::basic_string<wchar_t> может быть явно создан в дистрибутиве STL, избегая работы над его созданием в каждой единице перевода.

Явная реализация также полезна, когда вы хотите инкапсулировать реализацию шаблона и хотите, чтобы этот шаблон использовался только с хорошо известным набором типов. В этом случае в заголовочный файл можно поместить только объявления функций шаблона (бесплатные или члены) (.h/.hpp) и определите их в переводческой единице (.cpp).

Пример:

 // numeric_vector.h
//////////////////////////////////////////////////
template <typename T> class numeric_vector
{
...
void sort();
};// numeric_vector.cpp
//////////////////////////////////////////////////
// We know that it shall be used with doubles and ints only,
// so we explicitly instantiate it for doubles and ints
template class numeric_vector<int>;
template class numeric_vector<double>;

// Note that you could instantiate only specific
// members you need (functions and static data), not entire class:
template void numeric_vector<float>::sort();

template <typename T> void numeric_vector<T>::sort()
{
// Implementation
...
}

Также явное создание экземпляров может быть полезно, когда вам нужен экземплярный тип из шаблона, но внутри некоторой синтаксической конструкции, которая не запускает саму реализацию, например некоторые специфичные для компилятора мета-функции, такие как __declspec(uuid) в Visual Studio.

Обратите внимание на разницу с другим методом, который можно использовать для инкапсуляции реализации — явная специализация. При явной специализации вы должны предоставить конкретное определение для каждого типа, который будет специализированным. С явной реализацией у вас есть одно определение шаблона.

Рассмотрим тот же пример с явной специализацией:

Пример:

 // numeric_vector.h
//////////////////////////////////////////////////
template <typename T> class numeric_vector
{
...
void sort();
};

template <> class numeric_vector<int>
{
...
void sort();
};

template <> class numeric_vector<double>
{
...
void sort();
};

// Specializing separate members is also allowed
template <> void numeric_vector<float>::sort();

// numeric_vector.cpp
//////////////////////////////////////////////////
void numeric_vector<int>::sort()
{
// Implementation for int
...
}

void numeric_vector<double>::sort()
{
// Implementation for double
...
}

void numeric_vector<float>::sort()
{
// Implementation for float
...
}
7

Наличие явной специализации позволяет скрыть реализацию, которая, как вы знаете, обычно невозможна для шаблонов.

Я видел эту технику только один раз в библиотеке, которая обрабатывает геометрию, и они предоставили свой собственный векторный класс.

Так что вы могли бы использовать

lib::Vector<MyShape>

с некоторыми основными функциями, которые lib::Vector при условии, и основные реализации, и если вы использовали его со своими классами (некоторые, не все)

lib::Vector<lib::Polygon>

Вы бы использовали явную специализацию. У вас не будет доступа к реализации, но я держу пари, что за кулисами там происходили некоторые жесткие оптимизации.

5

Если вам действительно не нравится определение шаблонных функций в заголовочных файлах, вы можете определить функции в отдельном исходном файле и использовать явное создание экземпляров шаблона для создания экземпляров всех версий, которые вы используете. Тогда вам нужно только предварительные объявления в вашем заголовочном файле вместо полного определения.

0
По вопросам рекламы ammmcru@yandex.ru
Adblock
detector