Jar*_*d42 5 c++ using-declaration c++-concepts c++20
是否有其他方法可以using在概念/约束中进行一些声明?就像是:
template <typename T>
concept has_begin_v0 = requires (T t)
{
using std::begin; // KO
begin(t);
/*..*/
};
Run Code Online (Sandbox Code Playgroud)
我发现的可能的方法是:
使用中间体namespace
namespace detail
{
using std::begin;
template <typename T>
concept has_begin_v1 = requires (T t)
{
begin(t);
};
}
using detail::has_begin_v1;
Run Code Online (Sandbox Code Playgroud)
引入额外的命名空间:-(
使用 SFINAed lambda:
template <typename T>
concept has_begin_v2 = requires (T t)
{
[](){
using std::begin;
return [](auto&& inner) -> std::void_t<decltype(begin(inner))> {};
}()(t);
};
Run Code Online (Sandbox Code Playgroud)
这不是一个很好的语法。
使用限定调用和 adl 调用的“析取”:
template <typename T>
concept has_std_begin = requires (T t)
{
std::begin(t);
};
template <typename T>
concept has_adl_begin = requires (T t)
{
begin(t);
};
template <typename T>
concept has_begin_v3 = has_std_begin<T> || has_adl_begin<T>;
Run Code Online (Sandbox Code Playgroud)
IMO 更好,但似乎无法扩展,也不允许进一步发展(begin(t)与end(t)?)。
一般来说,你应该避免采取这种using std::begin伎俩。由于您已经在 C++20 中进行操作,因此您可以使用范围自定义点对象std::ranges::begin。它可以通过直接通话完成您所需的 ADL 体操,因此您不需要using std::begin.