通过using-directive调用开始和结束? [英] Invoking begin and end via using-directive?

查看:129
本文介绍了通过using-directive调用开始和结束?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

调用 swap 的成语是:

using std::swap
swap(foo, bar);

这样, swap std 命名空间之外的用户定义类型。

This way, swap can be overloaded for user-defined types outside of the std namespace.

我们应该调用 begin end 以同样的方式?

Should we invoke begin and end in the same fashion?

using std::begin;
using std::end;
some_algorithm(begin(some_container), end(some_container));

或者我们应该写:

some_algorithm(std::begin(some_container), std::end(some_container));


推荐答案

code> - 声明就是这样正确的方式IMO。这也是标准对循环范围的作用:如果没有开始结束成员存在,那么它将调用 begin(x) end(x) std 作为关联命名空间(即,如果ADL不存在,则它将找到 std :: begin std :: end 找到非成员开始结束)。

Using a using-declaration like that is the correct way IMO. It's also what the standard does with the range for loop: if there is no begin or end members present then it will call begin(x) and end(x) with std as an associated namespace (i.e. it will find std::begin and std::end if ADL doesn't find non-member begin and end).

如果你发现写 using std :: begin;使用std :: end; 所有的时间都很乏味,那么你可以使用 adl_begin adl_end 下面的函数:

If you find that writing using std::begin; using std::end; all the time is tedious then you can use the adl_begin and adl_end functions below:

namespace aux {

using std::begin;
using std::end;

template<class T>
auto adl_begin(T&& x) -> decltype(begin(std::forward<T>(x)));

template<class T>
auto adl_end(T&& x) -> decltype(end(std::forward<T>(x)));

template<class T>
constexpr bool is_array()
{
    using type = typename std::remove_reference<T>::type;
    return std::is_array<type>::value;
}

} // namespace aux

template<class T,
         class = typename std::enable_if<!aux::is_array<T>()>::type>
auto adl_begin(T&& x) -> decltype(aux::adl_begin(std::forward<T>(x)))
{
    using std::begin;
    return begin(std::forward<T>(x));
}

template<class T,
         class = typename std::enable_if<!aux::is_array<T>()>::type>
auto adl_end(T&& x) -> decltype(aux::adl_end(std::forward<T>(x)))
{
    using std::end;
    return end(std::forward<T>(x));
}

template<typename T, std::size_t N>
T* adl_begin(T (&x)[N])
{
    return std::begin(x);
}

template<typename T, std::size_t N>
T* adl_end(T (&x)[N])
{
    return std::end(x);
}

这段代码相当怪异。希望用C ++ 14,这可以变得不那么神秘:

This code is pretty monstrous. Hopefully with C++14 this can become less arcane:

template<typename T>
concept bool Not_array()
{
    using type = std::remove_reference_t<T>;
    return !std::is_array<type>::value;
}

decltype(auto) adl_begin(Not_array&& x)
{
    using std::begin;
    return begin(std::forward<Not_array>(x));
}

decltype(auto) adl_end(Not_array&& x)
{
    using std::end;
    return end(std::forward<Not_array>(x));
}

template<typename T, std::size_t N>
T* adl_begin(T (&x)[N])
{
    return std::begin(x);
}

template<typename T, std::size_t N>
T* adl_end(T (&x)[N])
{
    return std::end(x);
}

这篇关于通过using-directive调用开始和结束?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆