C++20概念:要求表达和完美转发
C++20 concept : requires expression and perfect forwarding
仅供参考:C++17 std::is_invocable_v 完全符合我的预期。
设想一个概念来检查是否可以使用特定参数类型调用可调用对象:
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;
};
在 requires 表达式中使用完美转发有意义吗?
在我看来答案是肯定的,因为请求可调用对象可能需要某些参数的右值。
但是 requires (Fn request, Args... args)
是否表现为关于 args...
左值性质的函数声明?
它的行为与它看起来的完全一样。这就是 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)...);
}
所以是的,如果你想通过概念进行转发,你的概念需要使用 &&
和转发。
仅供参考:C++17 std::is_invocable_v 完全符合我的预期。
设想一个概念来检查是否可以使用特定参数类型调用可调用对象:
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;
};
在 requires 表达式中使用完美转发有意义吗?
在我看来答案是肯定的,因为请求可调用对象可能需要某些参数的右值。
但是 requires (Fn request, Args... args)
是否表现为关于 args...
左值性质的函数声明?
它的行为与它看起来的完全一样。这就是 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)...);
}
所以是的,如果你想通过概念进行转发,你的概念需要使用 &&
和转发。