简体   繁体   中英

How to use using-declarations in constraint

Is there an alternative to have some using -declarations in concept/constraint? Something like:

template <typename T>
concept has_begin_v0 = requires (T t)
{
    using std::begin; // KO
    begin(t);
    /*..*/
};

The possible ways I have found are:

  • use intermediate namespace

     namespace detail { using std::begin; template <typename T> concept has_begin_v1 = requires (T t) { begin(t); }; } using detail::has_begin_v1;

    Introduces extra namespace:-(

  • 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); };

    Not a fine syntax.

  • use "disjunction" of qualified call and adl call:

     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>;

    The nicer IMO, but seems not to scale nor allow to go further (is begin(t) comparable with end(t) ?).

Demo

You should generally avoid having to do the using std::begin trick. Since you're already operating in C++20, you can use the ranges customization point object std::ranges::begin . It does the ADL gymnastics you need on a direct call, so you don't need using std::begin .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM