当“require 子句”被括号包围时,为什么还要用括号包围模板参数?

Bry*_*Yan 1 c++ c++-concepts c++20

当 被括号包围时,为什么要用括号包围模板参数require clause

template(typename This, typename Receiver)
    (requires same_as<remove_cvref_t<This>, type> AND
      receiver<Receiver> AND
      constructible_from<std::tuple<Values...>, member_t<This, std::tuple<Values...>>>)
friend auto tag_invoke(tag_t<connect>, This&& that, Receiver&& r)
    noexcept(std::is_nothrow_constructible_v<std::tuple<Values...>, member_t<This, std::tuple<Values...>>>)
    -> operation<Receiver, Values...> {
  return {static_cast<This&&>(that).values_, static_cast<Receiver&&>(r)};
}
Run Code Online (Sandbox Code Playgroud)

来自libunifex

康桓瑋*_*康桓瑋 5

当 require 子句被括号包围时,为什么要用括号包围模板参数?

你看到的部分template(typename This, typename Receiver)实际上是一个宏,其定义为

#if UNIFEX_CXX_CONCEPTS
  #define template(...) \
    template <__VA_ARGS__> UNIFEX_PP_EXPAND \
    /**/
#else
  #define template(...) \
    template <__VA_ARGS__ UNIFEX_TEMPLATE_SFINAE_AUX_ \
    /**/
#endif
Run Code Online (Sandbox Code Playgroud)

用于简化带有后缀的模板定义UNIFEX_PP_EXPAND