Использовать трюк определения std::function для conept с предикатами.

d-yaroshev
d-yaroshev

Реализация для Predicate: https://godbolt.org/g/bSuuDb

Я бы таким образом записывал и StrictWeakOrder, Invocable итд - везде где речь идет про что-то, чему в качестве параметров передаются другие аргументы.


Мне кажется, так получается чище и понятнее, при этом пара скобок не увеличивает длину выражения.

2
рейтинг
11 комментариев
yndx-antoshkka

Идея огонь! Скину авторам ranges TS.

yndx-antoshkka
yndx-antoshkka

Есть минусы в таком подходе - он не позволяет использовать сокращённый синтаксис https://godbolt.org/g/R3z5FF.

yndx-antoshkka
d-yaroshev

yndx-antoshkka, ой. А как terse syntax  подставляет имя неявного параметра?

d-yaroshev
Andrey

Я чего-то не догнал в чем идея. Если вызвать

#include <array>

bool is_even(int);

void test(std::array<int, 3> xs) {
    my_find_if(xs.begin(), xs.end(), &is_even);
}

то в compute_is_predicate придет identity<Fn(int)>, где Fn = bool (*)(int). Что в этом хорошего?

Andrey
d-yaroshev

Andrey, не очень вас понял.
Есть concepts, идея concepts в том чтобы ограничивать шаблоны.

Вопрос в том что сейчас есть concept Predicate, например: https://en.cppreference.com/w/cpp/concepts/Predicate

И для find_if, нужно чтобы функтор, который ему передается, был Predicate.

Сейчас это предлагается писать как:

template <typename I, typename P>
  requires ForwardIterator<I> && Predicate<P, ValueType<I>>
I find_if(I f, I l, P p);

Мне кажется, что понятнее написать:

template <typename I, typename P>
  requires ForwardIterator<I> && Predicate<P(ValueType<I>)>
I find_if(I f, I l, P p);

 

d-yaroshev
Andrey

Ок, в первый раз я Вас не понял. То что Вы предлагаете (если я правильно понял сейчас) невозможно -- concept definition (в отличие от class template) нельзя частично специализировать.

Andrey
d-yaroshev

Andrey, это абсолютно не страшно. Можете посмотреть на реализацию для Predicate из описания моего предложения.

d-yaroshev
Комментарий удален
d-yaroshev

Andrey, я что-то не понимаю( Какая разница как устроена шаблонная магия внутри стандартной библиотеки? Важно же какой интерфейс получает пользователь библиотеки, правда? Я могу не через  identity сделать https://godbolt.org/g/Da2Ft5

Вас смушает, что тип параметра шаблона не осмысленный? Ну это некоторый DSL, я бы сказал, достаточно понятный.

d-yaroshev
Andrey

передавать как шаблонный аргумент identity? Да так можно. Но тогда я возвращаюсь к своему первому вопросу -- зачем это делать, если получающийся тип лишен смысл -- это function type, return type которого это function-like type, к примеру, функция принимающая int и возвращающая pointer на функцию принимающую int и возвращающую bool. Это все чтобы в месте использования Predicate писать Predicate<P(ValueType<I>)> вместо Predicate<P, ValueType<I>>, потому что первая конструкция кажется Вам понятнее. Но если вспомнить реальные подставляемые значения P и ValueType<I>, bool(*)(int) и int соответственно, то что же в этом естественного?

Andrey
Andrey

d-yaroshev, ок, давайте сойдемся на том, что мне не нравится DSL в котором используются неосмысленные типы. Это вопрос вкуса, и спорить дальше смысла нет.

Andrey
Обновлено 
yndx-antoshkka

Мне подсказали, что комитет рассматривал и отказался от этой идеи. "Она ведёт к нерприятным сюрпризам из-за decay типов аргументов функции при формированиии типа функции."

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