Список возможных значений для аргумента шаблона.

Aracks
Aracks

Суть проблемы:

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

template<typename _CharT, typename _Traits, typename _Alloc>
class basic_string { /*...*/ };

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

1) Написать шаблон функции, но тогда он будет полностью в заголовочнике.

template<typename TChar>
void my_func(const std::basic_string<TChar>& cr_value) { /*...*/ }


2) Сделать несколько вариантов с разными типами строк, но тогда у мення будет куча копипаста.

void my_func(const std::string& cr_value);

void my_func(const std::wstring& cr_value);

void my_func(const std::u8string& cr_value);

void my_func(const std::u16string& cr_value);

void my_func(const std::u32string& cr_value);

/*И для каждой из них написать реализацию, в точности повторяющую остальные.*/

А вот если бы существовал способ ограничить набор возможных аргументов шаблона, то можно было бы перенести реализацию в *.cpp файл, а компилятор просто сгенерировал бы для неё все 5 специализаций разом. Это могло бы выглядеть как-то так:

1) В первом варианте создаётся шаблон, который в принципе нельзя специализировать ничем, кроме заданного набора типов.


____Заголовочник____

template<typename TChar = (char, wchar_t, char8_t, char16_t, char32_t)>
void my_func(const std::basic_string<TChar>& cr_value);

______CPP-файл______

template<typename TChar>
void my_func(const std::basic_string<TChar>& cr_value) { /*...*/ }

2) Во втором варианте создаётся шаблон, который можно специализировать разными типами, но вариант по умолчанию задан только для ограниченного набора типов.


____Заголовочник____

 

template<typename TChar>
void my_func(const std::basic_string<TChar>& cr_value);

______CPP-файл______

 

template<typename TChar = (char, wchar_t, char8_t, char16_t, char32_t)>
void my_func<TChar>(const std::basic_string<TChar>& cr_value) { /*...*/ }

 

-6
рейтинг
8 комментариев
Georgy Firsov

Так для этого есть концепты. Можно написать концепт как конъюнкцию из нескольких 

std::is_same
Georgy Firsov
Aracks

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

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

Aracks
Aracks

Georgy Firsov, а, да, и второй вариант использования, из предложенных мною, концептами, насколько я знаю, вообще не может быть реализован.

Aracks
Andrey

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

В header-е пишется объявление

template<typename TChar>
void my_func(const std::basic_string<TChar>& cr_value);

В .cpp она определяется, и явно инстацируется:

template void my_func(const std::string& cr_value);
template void my_func(const std::wstring& cr_value);
template void my_func(const std::u8string& cr_value);
template void my_func(const std::u16string& cr_value);
template void my_func(const std::u32string& cr_value);
Andrey
Aracks

Andrey, а реализации? Мне копипаст делать для всех?

Aracks
Aracks

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

Если же поместить в cpp, то придётся делать копипаст.

Aracks
Andrey

Aracks, копипаст делать не придется, почитайте о том что такое explicit template instantiation.

Andrey
Aracks

Andrey, да, прошу прощения. Это в точности то, что нужно, хотя и с более длинным синтаксисом.

Aracks
Другие идеи
Группа создана, чтобы собирать предложения к стандарту C++, организовывать их внутренние обсуждения, помогать готовить их для отправки в комитет и защищать на общих собраниях в рабочей группе по С++ Международной организации по стандартизации (ISO).
Все предложения