Явный экземпляр - когда он используется?
После нескольких недель перерыва я пытаюсь расширить и расширить свои знания шаблонов с помощью книги Templates – Полное руководство Дэвида Вандевоорда и Николая М. Йосуттиса, и то, что я пытаюсь понять в этот момент, - это явное создание шаблонов.
На самом деле у меня нет проблемы с механизмом как таковым, но я не могу представить ситуацию, в которой я хотел бы или хотел бы использовать эту функцию. Если кто-нибудь может объяснить это мне, я буду более чем благодарен.
Ответы
Ответ 1
Непосредственно скопировано из https://docs.microsoft.com/en-us/cpp/cpp/explicit-instantiation:
Вы можете использовать явное создание экземпляра для создания экземпляра шаблонного класса или функции без фактического использования его в вашем коде. Поскольку это полезно, когда вы создаете файлы библиотек (.lib), которые используют шаблоны для распространения, неиспользуемые определения шаблонов не помещаются в файлы объектов (.obj).
(Например, libstdc++ содержит явное инстанцирование std::basic_string<char,char_traits<char>,allocator<char> >
(который является std::string
), поэтому каждый раз, когда вы используете функции std::string
, тот же код функции не нужно копировать в объекты. Компилятору нужно только ссылаться (ссылаться) на libstdc++.)
Ответ 2
Если вы определяете класс шаблона, который вы хотите использовать только для нескольких явных типов.
Поместите объявление шаблона в файл заголовка так же, как обычный класс.
Поместите определение шаблона в исходный файл, как обычный класс.
Затем в конце исходного файла явно создается экземпляр только той версии, в которой вы хотите быть доступной.
Глупый пример:
// StringAdapter.h
template<typename T>
class StringAdapter
{
public:
StringAdapter(T* data);
void doAdapterStuff();
private:
std::basic_string<T> m_data;
};
typedef StringAdapter<char> StrAdapter;
typedef StringAdapter<wchar_t> WStrAdapter;
Источник:
// StringAdapter.cpp
#include "StringAdapter.h"
template<typename T>
StringAdapter<T>::StringAdapter(T* data)
:m_data(data)
{}
template<typename T>
void StringAdapter<T>::doAdapterStuff()
{
/* Manipulate a string */
}
// Explicitly instantiate only the classes you want to be defined.
// In this case I only want the template to work with characters but
// I want to support both char and wchar_t with the same code.
template class StringAdapter<char>;
template class StringAdapter<wchar_t>;
Главная
#include "StringAdapter.h"
// Note: Main can not see the definition of the template from here (just the declaration)
// So it relies on the explicit instantiation to make sure it links.
int main()
{
StrAdapter x("hi There");
x.doAdapterStuff();
}
Ответ 3
Это зависит от модели компилятора - видимо, есть модель Borland и модель CFront. И тогда это зависит также от вашего намерения - если вы пишете библиотеку, вы можете (как указано выше) явно создавать специализированные специализации.
На странице GNU c++ обсуждаются модели здесь https://gcc.gnu.org/onlinedocs/gcc-4.5.2/gcc/Template-Instantiation.html.