如何在约束中使用using-declarations



在概念/约束中有一些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

最新更新