Концепция C ++ 20: требует выражения и идеальной пересылки - PullRequest
6 голосов
/ 20 января 2020

К вашему сведению: C ++ 17 std :: is_invocable_v делает именно то, что я ожидал.

Представьте себе концепцию проверки возможности вызова вызываемого объекта с указанными c типами аргументов:

template <typename Fn, typename... Args>
concept has_request_interface = requires (Fn request, Args&&... args)
{
    { std::invoke(request, std::forward<Args>(args)...) }-> Status;
};

против

template <typename Fn, typename... Args>
concept has_request_interface = requires (Fn request, Args... args)
{
    { std::invoke(request, args...) }-> Status;
};

Имеет ли смысл использование совершенной пересылки в выражениях требует?

Мне кажется, что ответ положительный, потому что вызываемый объект запроса может ожидать значения rvalues для некоторых аргументов.

Но requires (Fn request, Args... args) ведет себя как объявление функции относительно lvalue природы args...?

1 Ответ

5 голосов
/ 20 января 2020

Он будет вести себя так же, как выглядит. В этом и заключается смысл выражения requires: чтобы все это выглядело как C ++. Так что он будет вести себя как C ++.

Важно то, как вы используете концепцию. То есть, когда вы requires используете какой-то шаблон на его основе, вы должны правильно вызвать концепцию. Например:

template<typename Func, typename ...Args
void constrained(Func func, Args &&...args)
  requires has_request_interface<Func, Args...>
{
  Status status = func(std::forward<Args>(args)...);
}

Так что, если вы хотите, чтобы пересылка по концепции работала, ваша концепция должна использовать && и переадресацию.

...