Как принудительно создать экземпляр экземпляра С++ для экземпляра?

См. главу. У меня есть шаблон. Я хочу заставить конкретный экземпляр шаблона для создания экземпляра. Как это сделать?

В частности, вы можете принудительно создать абстрактный шаблонный класс?


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

т

template<class T>
OS_EXPORT_DECL class MyTmpl
{
    T *item1;
public:
    inline T *simpleGetT() { return(item1); } /* small inline code in here */ } 
    T *doSomeReallyBigMergeStuff(T *b); // note only declaration here
};

// *** implementation source file only seen inside library

template<class T>
MyTmpl<T>::doSomeReallyBigMergeStuff(T *b)
{
    ... a really big method, but don't want to duplicate it, 
        so it is a template ...
}

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

????? В частности, я создаю библиотеку для нескольких версий MSC и GCC и компиляторов Intel.

Ответ 1

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

Принудительное создание экземпляра выполняется путем предоставления всех типов явно:

template class std::vector<int>;

Приход часто задаваемые вопросы о часах описывает некоторые проблемы.

Ответ 2

То, что вы также можете попробовать, - это явное создание экземпляра:

template class vector<int>;                    // class
template int& vector<int>::operator[](int);    // member
template int convert<int,double>(double);      // function

Ответ 3

Вы можете принудительно создать экземпляр, используя шаблон с нужным параметром. Например, вы можете определить функцию, используя все необходимые методы:

void force_int_instance() {
  Abstract<int> *a;
  a->some_method();
  a->some_other_method(1, 2, 3);
}

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

Ответ 4

Если я правильно понял ваш вопрос, у вас есть класс шаблона, и вы хотите заставить компилятор генерировать код для использования с определенным типом. Например, вы можете обеспечить код для std::vector <int> существует в вашей программе.

Лучший способ обеспечить это - просто создать экземпляр класса:

void EnsureInstantiation()
{
    std::vector<int> intvector;
    std::vector<boo> boolvector;
    /// etc.
}

Фокус в том, что вам даже не нужно вызывать EnsureInstantiation в любом месте вашего кода. Просто убедитесь, что он не является статичным или компилятор может его оптимизировать.

Ответ 5

абстрактный класс не может быть создан. Вероятно, вы хотите что-то сделать в соответствии с:

Abstract *a = new Implementation(...);

Чтобы принудительно создать шаблон, вызовите шаблон с параметрами шаблона:

std::max<int>(...);
std::pair<int, string>(...);

Ответ 6

Я собираюсь ответить на то, что, как я думаю, вы имели в виду, а не то, что вы сказали.

Я предполагаю, что проблема - одна из двух вещей. Во-первых, у вас есть код в шаблоне, который не компилируется при компиляции самого файла шаблона, что может быть очень неприятным. Это можно зафиксировать в настройках вашего компилятора.

Другой - вы хотите иметь что-то особенное для определенного типа, возможно, для его отладки. Это называется явным instanciation, но на самом деле не стимулирует что-либо, просто гарантирует, что он всегда будет определен после этой точки.

http://publib.boulder.ibm.com/infocenter/macxhelp/v6v81/topic/com.ibm.vacpp6m.doc/language/ref/clrc16explicit_instantiation.htm