在概念/约束中有一些using
声明的替代方案吗?比如:
template <typename T>
concept has_begin_v0 = requires (T t)
{
using std::begin; // KO
begin(t);
/*..*/
};
我已经找到了可能的方法:
使用中间体
namespace
namespace detail { using std::begin; template <typename T> concept has_begin_v1 = requires (T t) { begin(t); }; } using detail::has_begin_v1;
引入额外的命名空间:-(
)using 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); };
语法不太好。
使用"disjunction"合格呼叫和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>;
更好的IMO,但似乎不能扩展,也不允许进一步(
begin(t)
与end(t)
可比较吗?)。
您通常应该避免使用using std::begin
技巧。由于您已经在c++ 20中操作,您可以使用范围自定义点对象std::ranges::begin
。它做了你在直接呼叫中需要的ADL体操,所以你不需要using std::begin
。