Поскольку понятия определены как предикаты времени компиляции, возможно ли также фактически использовать эти предикаты для алгоритмов времени компиляции? Например, можно ли проверить, все ли типы в кортеже соответствуют концепции? Насколько я видел, невозможно передать концепцию какой-либо функции, что побуждает меня вернуться к использованию шаблонов для этих случаев.
#include <type_traits>
template<typename T>
concept FloatLike = std::is_same_v<T, float>;
struct IsFloat
{
template<typename U>
constexpr static bool test()
{
return FloatLike<U>;
}
};
template<typename Predicate, typename... T>
constexpr bool all_types()
{
return (Predicate::template test<T>() && ...);
}
int main()
{
static_assert(all_types<IsFloat, float, float>());
static_assert(!all_types<IsFloat, float, int>());
}
Я хотел бы сделать что-то вроде этого, поэтому мне не нужно постоянно оборачивать концепцию, чтобы иметь возможность использовать ее:
template<concept Predicate, typename... T>
constexpr bool all_types()
{
return (Predicate<T> && ...);
}
int main()
{
static_assert(all_types<FloatLike, float, float>());
static_assert(!all_types<FloatLike, float, int>());
}
Есть ли способ приблизиться к этому?
all_types()
можно значительно упростить использование выражений складывания... &&
:return (... && Predicate::template test<Ts>());
Ответы:
Ну нет, не совсем. Не в C ++ 20. Сегодня в языке нет понятия концептуального параметра-шаблона. Даже переменные шаблоны не могут использоваться в качестве параметров шаблона. Так что, если у вас есть концепция для начала, мы не можем избежать упаковки.
Но то, что мы можем сделать, это написать более простые обертки. Если мы согласимся использовать в качестве предикатов признаки типа «старого стиля», особенно те, которые ведут себя как
std::integral_constant
s, то мы можем получить довольно краткие определения «концептов», которые можно использовать в качестве предикатов.Это настолько хорошо, насколько это возможно , насколько я могу видеть.
источник
Если ваша цель - «проверить, все ли типы в кортеже соответствуют концепции» , то вы можете сделать что-то вроде этого:
LIVE DEMO
источник
AllSame
вариадик? Каждый параметр шаблона в пакете, введенный ограничением типа, уже ограничен отдельно.*_foo()
?...
onTs
и тот,&& ...
который использует его. (Очевидно, что имяAllSame
было бы тогда неуместным, но я не уверен, почему я хотел бы выразить счет в одинарном, как в<int,int,int>
любом случае.)AllSame
ноSameAs
(см. En.cppreference.com/w/cpp/concepts/same_as ), и OP хотел иметь концепцию, которая принимает переменное число параметров шаблона.std::same_as
. Я не думаю, что вариационная часть была смыслом: это была (желаемая) переменная идентичность концепции. И моя точка зрения заключалась в том, что вариационный аспект вашего примера концепции не имеет отношения к его использованию (потому что не вариадические концепции уже работают с пакетами параметров шаблона).