Как заставить конкретный экземпляр шаблона C++ создавать экземпляр?

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

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


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

ie:

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.


person anon    schedule 28.01.2010    source источник
comment
Можете ли вы привести пример? Что именно вы подразумеваете под созданием экземпляра абстрактного класса шаблона?   -  person jalf    schedule 28.01.2010


Ответы (6)


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

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

template class std::vector<int>;

Comeaus Часто задаваемые вопросы о шаблонах подробно описывает связанные с этим вопросы.

person Georg Fritzsche    schedule 28.01.2010
comment
обратите внимание, что вы должны сделать это после того, как все шаблоны и код для них будут объявлены безопасными. - person peterk; 16.10.2011
comment
@peterk, объявленный безопасным, заставил меня задуматься примерно на 20 секунд. Затем меня осенило после того, как... было объявлено, чтобы быть в безопасности. -- ржу не могу - person sehe; 18.11.2012
comment
На самом деле это синтаксическая ошибка, по крайней мере, в gcc 4.1; это должно быть template class std::vector<int> (ответ Александра ниже правильный) - person Redmumba; 19.07.2013

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

template class vector<int>;                    // class
template int& vector<int>::operator[](int);    // member
template int convert<int,double>(double);      // function
person Alexander Poluektov    schedule 28.01.2010
comment
Пока я не добрался до этого поста, я несколько дней пытался использовать шаблон ‹› и не мог понять, в чем проблема. Использование только шаблона без угловых скобок работало отлично. - person twerdster; 06.06.2012

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

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

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

person sth    schedule 28.01.2010

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

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

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

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

person Anton    schedule 28.01.2010

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

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

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

std::max<int>(...);
std::pair<int, string>(...);
person Anycorn    schedule 28.01.2010

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

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

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

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

person Charles Eli Cheese    schedule 28.01.2010