шаблоны понимания проблем в с ++ - PullRequest
5 голосов
/ 30 марта 2010

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

Например, main.cpp вызывает функцию шаблона из файла test.h, компилятор генерирует объектный файл main.o, Функция шаблона находится внутри файла main.o? потому что код шаблона не встроен, не так ли?

Ответы [ 5 ]

4 голосов
/ 30 марта 2010

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

Так что вы должны увидеть документацию вашего компилятора для более подробной информации.

3 голосов
/ 30 марта 2010

Да, код функции шаблона выдается в файле main.o. Некоторые из них могут быть встроенными, как любой другой код, но в общем случае код для шаблонов генерируется в любом файле, в котором шаблон создан . Думайте об этом как о начале создания экземпляра кода шаблона для получения обычных функций, не связанных с шаблоном, а затем о компиляции этих функций с использованием любых встроенных функций и оптимизации, применяемых компилятором для любой другой функции.

Когда один и тот же экземпляр шаблона (например, std::vector<int>) встречается в нескольких блоках компиляции (.cpp файлов), возникает небольшая трудность, потому что код создается в каждом из них. Существуют различные способы решения этой проблемы, иногда включающие этап очистки на этапе компоновки, где повторяющиеся экземпляры шаблона разрешаются в один; ваше руководство по компилятору может предоставить больше информации о том, как именно он справляется с этой ситуацией.

1 голос
/ 30 марта 2010

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

template< typename T >
void f()
{
  blah
}

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

template< typename T >
void f()
{
  typename T::nested_type x;
}

T::nested_type можно проверить только после создания экземпляра шаблона и указания фактического типа для T. Тем не менее, базовая проверка («данный T::nested_type является типом, это допустимое определение переменной?») Выполняется в тот момент, когда компилятор встречает определение шаблона. (Вот почему требуется typename, кстати. В зависимости от T, T::nested_type также может быть именем члена T или статического члена данных - что может привести к синтаксической ошибке T::nested_type x;. Поэтому мы должны указать компилятору трактовать T::nested_type как имя типа.)

0 голосов
/ 30 марта 2010

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

0 голосов
/ 30 марта 2010

Он всегда встроенный (это означает, что это всегда внутренняя связь, имеющая встроенную семантику). На самом деле он может быть не встроенным, как встроенная функция, однако шаблон не является кодом. Это «шаблон для создания кода». Следовательно, он обычно находится в заголовке, за исключением особых случаев, см. Ниже.

Была идея сделать что-то еще под кодовым названием "ключевое слово экспорта". Он был удален из стандарта.

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

template class std::vector<MyClass>;

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

extern template class std::vector<MyClass>; // C++0x only

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...