Есть ли что-нибудь в стандарте C ++ 0x для поддержки отдельной компиляции шаблонов? - PullRequest
3 голосов
/ 24 июня 2011

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

template<typename T>
class A {
public:
  void f() { ... }
};

Так что в другом источнике я бы написал:

#include <A.hh>
A<int> a1;
a1.f();

A<double> a2;
a2.f();

Иногда, когда я отчаянно пытался не встроить большие методы, я вручную определял, какие классы будут использоваться в исходном файле, но это действительно противно:

template<typename T>
A::A() { ... }

template<typename T>
void A::f() { ... }

A<int>; // manually trigger code generation for int and double
A<double>; 

Очевидно, что разные IDE и компиляторы имеют механизмы для поддержки этого. Есть ли что-то стандартное, что было предписано, и / или g ++ поддерживает что-то подобное?

Ответы [ 4 ]

5 голосов
/ 24 июня 2011

В предлагаемом стандарте C ++ 0x ничего нет.Фактически, export template был удален (так или иначе, немногие компиляторы реализовали его).

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

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

3 голосов
/ 24 июня 2011

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

 A<int>; // manually trigger code generation for int and double
 A<double>; 

Это недопустимо (я предполагаю, что вы хотели объявить фиктивныйПеременные здесь и пропустили их имя).Ниже мы увидим, почему

Есть ли что-то стандартное, что было предписано, и / или g ++ поддерживает что-то подобное?

C ++ 03 имел что-то под названием export, но это оказалось ошибкой.EDG реализовала эту функцию, и их опыт показал, что ее реализация не стоит того.И он не предоставляет полезной функции, которую обычно дает отдельная компиляция: Скрытие кода шаблонов, который вы когда-то компилировали.export все еще требуется код шаблонов, будь то в необработанном виде или закодированный на языке компилятора среднего уровня.См. Почему мы не можем позволить себе экспорт .Короткий пример приведен работником EDG Дэвидом Вандеворде здесь .

Для C ++ 0x и для экспорта без C ++ 0x мы имеем

Aшаблон функции, функция-член шаблона класса или статический член данных шаблона класса должны быть определены в каждой единице перевода, в которой он неявно создается (14.7.1), если в какой-то части не определена соответствующая специализация (14.7.2) в некоторыхпереводческий блок;Диагностика не требуется

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

Таким образом, вы явно создаете экземпляр шаблона класса, который также явно создает экземпляры его функций-членов следующим образом:

template class A<int>;
template class A<double>;
3 голосов
/ 24 июня 2011

C ++ 0x имеет extern template, что позволяет предотвратить создание экземпляров определенных шаблонов в модуле компиляции. Так что если у вас есть шаблон класса SomeClass, вы можете поместить это в заголовок:

extern template SomeClass<int>;
extern template SomeClass<double>;

Это предотвратит создание экземпляров шаблона пользователями. В файле .cpp для шаблона вы можете принудительно создать экземпляр с помощью следующего синтаксиса:

template SomeClass<int>;
template SomeClass<double>;
1 голос
/ 24 июня 2011

Эта функция, называемая export, присутствует даже в текущем стандарте C ++. К сожалению, большинство компиляторов, включая gcc, не поддерживают его. Смотрите здесь http://gcc.gnu.org/bugs/

...