Итак, мы с коллегой обсуждали преимущества явного создания шаблона, когда дело доходило до сокращения времени компиляции, отделяя объявление от определения и не влияя на производительность математической библиотеки C++, которую я написал, используется для других проектов.Явное создание экземпляра шаблона с inlining
По существу у меня есть библиотека полезных математических функций, предназначенных для работы с примитивами, такими как Vector3, Vector4, Quaternion и т. Д. Все они предназначены для использования с аргументом шаблона, который является float или double (а в некоторых случаях int).
Так что я не должен писать эти функции дважды, один раз для поплавков один раз для двойного, реализации функции являются шаблонными, например, так:
template<typename T>
Vector3<T> foo(const Vector4<T>& a,
const Quaternion<T>& b)
{ do something... }
Все определены в заголовочных файлах (поэтому они неявно для вставки). Большинство из этих функций являются короткими и, как надеются, будут встроены во время компиляции.
Заголовки становятся довольно большими, хотя время сборки увеличивается, и его трудно найти существование функций, просто взглянув на заголовки (это одна из многих причин, по которой мне нравится разделять объявление от реализаций).
Так что я могу использовать явный шаблон экземпляра в сопроводительном файле .cpp, например, так:
//in .h
template<typename T>
Vector3<T> foo(const Vector4<T>& a,
const Quaternion<T>& b)
{ do something... }
//in .cpp
template Vector3<float> foo<float>(const Vector4<float>& a,
const Quaternion<float>& b);
template Vector3<double> foo<double>(const Vector4<double>& a,
const Quaternion<double>& b);
Это должно помочь со временем компиляции? Это повлияет на возможность возможности встроенных функций? Являются ли ответы на любой из этих вопросов, как правило, конкретным компилятором?
Дополнительным преимуществом является то, что он проверяет, что функция компилируется, даже если я еще не использовал ее.
Кроме того, я мог бы сделать это:
//in .h
template<typename T>
Vector3<T> foo(const Vector4<T>& a,
const Quaternion<T>& b);
//in .cpp
template<typename T>
Vector3<T> foo(const Vector4<T>& a,
const Quaternion<T>& b)
{ do something... }
template Vector3<float> foo<float>(const Vector4<float>& a,
const Quaternion<float>& b);
template Vector3<double> foo<double>(const Vector4<double>& a,
const Quaternion<double>& b);
Те же вопросы для этого метода:
Это должно помочь со временем компиляции? Это повлияет на возможность возможности встроенных функций? Являются ли ответы на любой из этих вопросов, как правило, конкретным компилятором?
Я ожидаю, что возможность встраивания определенно будет затронута, учитывая, что определение не находится в заголовке.
Приятно, что ему удается отделить объявление и определение шаблонных функций (для конкретных аргументов шаблона), не прибегая к использованию чего-то вроде использования .inl, включенного в нижней части файла .h. Это также скрывает реализацию от пользователя библиотеки, которая является полезной (но еще не совсем необходимой), но при этом все еще можно использовать шаблоны, поэтому мне не нужно выполнять функцию N раз.
Есть ли способ разрешить встраивание путем настройки метода?
Мне было сложно просто поработать в поисках ответа на эти вопросы, и стандартная спецификация трудно понять по этим темам (по крайней мере для меня).
BTW, ожидается, что он будет скомпилирован с VS2010, VS2012 и GCC 4.7.
Любая помощь будет оценена по достоинству.
Благодаря
Я не думаю, что есть много компиляторов, которые позволяют создавать шаблоны вне заголовков ... –
@MatsPetersson: Это самое загадочное заявление, которое я слышал весь день. –
@MatsPetersson Это не так, обычные компиляторы не имеют понятия «файл заголовка». После того, как вы '# include' заголовочный файл в файле cpp, это как если бы заголовочный файл был частью файла cpp. Вероятно, вы имеете в виду, что определение метода/класса шаблона должно быть доступно в текущем блоке перевода, если оно создается для типа, который не создается в каких-либо других единицах перевода (файлы объектов, которые он получит связанный с). Но если вы явно создаете экземпляры в одном для всех типов, которые вам нужны (как OP), вам нужны только объявления в файлах заголовков. – Oguk