Я смотрю http://trac.webkit.org/browser/trunk/Source/JavaScriptCore/parser/Lexer.h и http://trac.webkit.org/browser/trunk/Source/JavaScriptCore/parser/Lexer.cpp
В заголовке на строке 196 имеется фрагмент кода
template <bool shouldBuildIdentifiers> ALWAYS_INLINE JSTokenType parseIdentifier(JSTokenData*, unsigned lexerFlags, bool strictMode);
Я вижу реализацию этого в файле cpp как
template <>
template <bool shouldCreateIdentifier> ALWAYS_INLINE JSTokenType Lexer<LChar>::parseIdentifier(JSTokenData* tokenData, unsigned lexerFlags, bool strictMode)
Мое понимание синтаксиса заключается в том, что мы определяем/специализируем функцию для Lexer типа LChar. Это верно? Я читал (почему шаблоны могут быть реализованы только в файле заголовка?), Что в идеале это должно быть сделано в файле заголовка.
Также стареют ли компиляторы C++ для синтаксиса? Mine - mips-linux-g++ v 4.1.0. Я получаю "идентификатор шаблона не соответствует объявлению шаблона"
Ваше понимание верное. Bool по-прежнему разрешается изменять шаблон метода, а специализация - для класса.
Хотя обычно шаблоны специализируются и реализуются в файле заголовков, альтернативой является добавление объявления вперед для специализации, и компилятор найдет его. Однако реализация должна быть связана с другим файлом, как и любая другая функция с отдельным объявлением и определением. Это имеет недостаток, что вложение не произойдет без оптимизации времени ссылки, но имеет потенциал роста, поэтому гораздо меньше кода нужно анализировать всякий раз, когда используется шаблон. В крупных проектах это может значительно улучшить время компиляции.
В этом случае разработчики классов решили, что есть только два способа, которыми этот класс когда-либо будет создан: с LChar и UChar (см. Комментарий к строке 1930). Поэтому они могут поместить свои реализации в.cpp файл и путем создания экземпляров обоих шаблонов в нижней части файла, все будет разрешено на этом этапе.
Шаблоны могут использоваться для реализации полностью общих классов (например, std::vector
), которые ожидают чего-либо, но могут также использоваться вместо виртуального метода, если вы считаете, что маловероятно, что вам понадобится больше, чем несколько реализаций, чтобы по-прежнему пользоваться преимуществами от повторного использования кода.
Что касается g++ 4.1.0, я только что проверил и увидел его почти 9 лет! Так много ошибок, связанных с шаблонами, были исправлены с тех пор, что если вы делаете что-то нетривиальное с ними, действительно стоит попробовать обновить.
T
вtemplate <typename T> class Lexer
), а второй - к методу (bool shouldCreateIdentifier
). Мы устанавливаемT
чтобы бытьLChar
, но мы все еще позволяемshouldCreateIdentifier
принимать другие значения. Это также известно как частичная специализация.