Это правильное использование концепций C ++ 20?

У меня есть простой класс Vec3<T>, и я хотел бы обновить его, используя концепции C ++ 20 (Clang 10.0.0 с -std = c ++ 20). Новая версия выглядит примерно так:

template <typename T> concept Arithmetic = std::is_arithmetic_v<T>;
template <typename T> concept FloatingPoint = std::is_floating_point_v<T>;

template <Arithmetic T> struct Vec3 {
  T x, y, z;

  /* operator overloading, etc.. */
  
  void normalize() requires FloatingPoint<T>;
};

Это правильное использование концепций C ++ 20? основное руководство T11 рекомендует использовать стандартные концепции как как можно больше, но я не смог найти те, которые хотел, в списке именованных требований C ++, ни в заголовочном файле <concepts>. Это потому, что мои концепции слишком специфичны и вообще не должны быть концепциями?

В моем исходном коде для достижения конечного результата используется сочетание static_assert и SFINAE.


person Touloudou    schedule 04.07.2020    source источник
comment
std::floating_point   -  person Evg    schedule 04.07.2020
comment
Спасибо. По какой причине std::is_floating_point получил свою концепцию, а не std::is_arithmetic?   -  person Touloudou    schedule 04.07.2020
comment
Не полностью ортогонально определенная функция? Честно говоря, в C ++ есть множество функций, которые реализованы крайне неполно. Это позволяет языку иметь еще несколько функций за счет того, что вам нужно помнить все особые случаи ...   -  person cmaster - reinstate monica    schedule 04.07.2020
comment
Кстати, подумайте о том, чтобы сделать normalize() бесплатной функцией с параметром Vec3<T>&.   -  person Evg    schedule 04.07.2020


Ответы (1)


У нас уже есть концепция типа с плавающей запятой, это std::floating_point. Отсутствие std::arithmetic кажется недосмотром и уже было отмечено, см. N4844, стр. 50:

США 193. В C ++ 20 отсутствует концепция арифметических типов. Это упущение вызывает удивление, поскольку это довольно распространенный вариант использования. Например, предположим, что я хочу написать функцию, возводящую число в квадрат. До C ++ 20 я мог бы написать:

template <typename T>
auto square(T x) {return x * x;}

В C ++ 20 казалось бы естественным написать:

auto square(std::arithmetic auto x) {return x * x;}

Однако такая концепция стандартной библиотеки отсутствует! Вместо этого мы должны написать более подробный:

template <typename T> requires std::is_arithmetic_v<T>
auto square(T x) {return x * x;}

Предлагаемое изменение:

template<class T>
concept arithmetic = is_arithmetic_v<T>;

Но вопрос о том, как следует определять std::arithmetic, не так прост, как может показаться. См. этот вопрос. Как отметил в комментарии Барри, предложенное изменение было отклонено.

person Evg    schedule 04.07.2020
comment
Этот комментарий NB был отклонен - person Barry; 04.07.2020