Как в C++ 20 ограничить шаблон целочисленными типами (int, long, long long, unsigned long long)?
В последней (20-й) версии С++ появились конструкции которые позволяют каким то образом ограничить template. Однако как это правильно сделать я пока не могу разобраться.
Помогите мне ограничить функцию только целочисленными типами.
/*
* For a given number the function returns unsorted vector of it's factors.
* Time Complexity of the algorithm is O(sqrt(N)).
*/
template <class T>
vector<T> factors(T number) {
vector<T> divisors;
for (T divisor = sqrt(number); divisor > 0; --divisor) {
if (number % divisor == 0) {
divisors.push_back(divisor);
T paired_divisor = number / divisor;
if (paired_divisor != divisor) {
divisors.push_back(paired_divisor);
}
}
}
return divisors;
}
Ответы (1 шт):
Автор решения: HolyBlackCat
→ Ссылка
Под целочисленные типы в стандартной библиотеке есть готовый концепт. Пользоваться им можно вот так:
#include <concepts>
template <std::integral T>
vector<T> factors(T number) {...}
Свои концепты можно делать так:
template < параметры (например typename T) > concept имя = булево выражение (константа времени компиляции).
Например, std::integral задается как template <typename T> concept integral = std::is_integral_v<T>;.
Для использования концептов есть куча вариантов синтаксиса. Попробую сжато описать:
- Просто как булево выражение, например
if (std::integral<T>) template <std::integral T>
Обратите внимание, что тут не указывается шаблонный параметр концепта - в него ставитсяT. Если параметров больше одного, то все кроме первого нужно указывать самому, напримерtemplate <std::derived_from<X> T>принимает любыеT, для которых истинноstd::derived_from<T, X>.- В C++20 разрешили
autoв параметрах функций (как в лямбдах), что неявно создает шаблон.
Теперь и там и там можно делать еще и так:void foo(std::integral auto x). - В целом в C++20 можно вешать произвольное условие-ограничение на шаблон, в виде булевого выражения.
template <std::integral T>эквивалентноtemplate <typename T> requires std::integral<T>. Для шаблонов функцийrequiresможно указывать не только после шаблонных параметров, но и после обычных параметров - разница минимальная. - Возможно еще что-то забыл.