В чем разница между использованием концепции напрямую вместо `typename` и использованием ключевого слова `requires`? Или это просто вопрос стиля?

Я пытаюсь разобраться concepts в C++20. Рассмотрим следующую (очень простую) концепцию:

template <typename T>
concept Float = requires
{
    std::floating_point<T>;
};

Я могу написать шаблонный класс, используя эту концепцию двумя способами:

template <Float T>
class MyClass {
public:
    MyClass(T val) : value{ val } {};
private:
    T value;
};

Или я могу сделать

template <typename T> requires Float<T>
class MyClass {
public:
    MyClass(T val) : value{ val } {};
private:
    T value;
};

В этом конкретном примере они ведут себя точно так же. Хотя всегда ли это так? Существуют ли ситуации, в которых проще выразить какое-либо ограничение с помощью синтаксиса template <...> requires ...? Или это просто предпочтение/соглашение о стиле?

Единственное, о чем я могу сейчас подумать, это то, что использование синтаксиса template <...> requires ... может позволить вам представлять реляционные ограничения между несколькими аргументами шаблона, тогда как синтаксис template <CONCEPT T> позволяет вам представлять ограничение только для одного аргумента?

Любое руководство будет высоко оценено.

Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
3
0
99
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

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

Например:

template <Concept auto value>
class foo {...};

//becomes

template <auto value> requires Concept<decltype(value)>
class foo {...};
Ответ принят как подходящий

Нет никакой разницы между:

template <Float T>

и

template <typename T> requires Float<T>

Они означают одно и то же. Если вы объявляете шаблон, а затем определяете его позже, вам придется использовать один и тот же синтаксис в обоих местах, но оба синтаксиса означают одно и то же.

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

Обратите внимание, что синтаксис ограничения типа может выражать ограничения нескольких типов. Например, типичный шаблон диапазонов:

template <typename I, typename S>
    requires input_iterator<I>
         and sentinel_for<S, I>
void algo(I, S);

можно записать сокращенно:

template <input_iterator I, sentinel_for<I> S>
void algo(I, S);

Ааа, на самом деле меня это интересовало отдельно: как обрабатывать концепции/требования при объявлении и определении шаблонов в разных местах. Приятно знать, что синтаксис должен совпадать (хотя это несколько раздражает, что его нужно обрабатывать в обоих местах, особенно для большого класса, это делает очень громоздким объявление в .hpp, а затем определение в .ipp

Chris Gnam 24.05.2024 19:14

Интересно, что gcc позволяет использовать две формы ограничений взаимозаменяемо в объявлении и определении, требуя, чтобы они соответствовали семантически, а не лексически. Поскольку gcc — единственный из трех основных компиляторов, который допускает, что это, вероятно, расширение, а не стандартное требование: gcc.godbolt.org/z/zzvded9ro

Gene 13.06.2024 00:04

Другие вопросы по теме