Я просматривал рабочий проект N3291 C ++ 0x.И мне было любопытно по поводу шаблона extern.Раздел 14.7.3 гласит:
За исключением встроенных функций и специализаций шаблонов классов, явные объявления создания экземпляров имеют эффект подавления неявного создания объекта, к которому они относятся.
К вашему сведению: термин "явное объявление экземпляра" является стандартным для extern template
.Это было определено в разделе 14.7.2.
Звучит так, словно говорится, что если вы используете extern template std::vector<int>
, то выполнение каких-либо действий, которые обычно неявно создаются для std::vector<int>
, не приведет к этому.
Следующий абзац более интересен:
Если объект является предметом как явного объявления экземпляра, так и явного определения экземпляра в той же единице перевода, определение должно следовать за объявлением.Сущность, которая является предметом явного объявления экземпляра и которая также используется таким образом, который в противном случае вызвал бы неявное создание экземпляра (14.7.1) в модуле перевода, должна быть объектом явного определения экземпляра где-то в программе;в противном случае программа некорректна, диагностика не требуется.
К вашему сведению: термин «явное определение экземпляра» является стандартным для следующих вещей: template std::vector<int>
.То есть без extern
.
Для меня эти две вещи говорят, что extern template
предотвращает неявную реализацию, но не предотвращает явную реализацию.Поэтому, если вы сделаете это:
extern template std::vector<int>;
template std::vector<int>;
Вторая строка эффективно отрицает первую, явно выполняя то, что не позволяло первой строке произойти неявно.
Проблема заключается в следующем: Visual Studio 2008 не делаетКажется, я согласен.Я хочу использовать extern template
, чтобы пользователи неявно создавали экземпляры некоторых часто используемых шаблонов, чтобы я мог их явно создавать в файлах .cpp для сокращения времени компиляции.Шаблоны будут создаваться только один раз.
Проблема в том, что мне нужно в основном #ifdef вокруг них в VS2008.Потому что, если единица перевода увидит версию extern
и версию, отличную от extern
, она выиграет версию extern
, и никто не сможет ее реализовать.А потом приходят ошибки компоновщика.
Итак, мои вопросы:
- Какое правильное поведение в соответствии с C ++ 0x?Должен ли
extern template
предотвратить явное создание экземпляра или нет? - Если ответ на предыдущий вопрос таков, что не должен, то VS2008 ошибочен (предоставлено, оно было написано задолго до спецификации, поэтомуих вина).Как VS2010 справляется с этим?Это реализует правильное
extern template
поведение?