gpt4 book ai didi

c++ - 为什么 Boost.Range range_begin/end 自由函数对于 const 和非 const 引用都重载了?

转载 作者:行者123 更新时间:2023-11-30 02:48:06 24 4
gpt4 key购买 nike

我在 Boost.Range 中发现了这个有趣的部分:

提供时free-standing functions range_begin/end(), the docs state that :

... range_begin() and range_end() must be overloaded for both const and mutable reference arguments.

事实上,看看他们在 end.hpp 中的默认值,我们看到:

    //////////////////////////////////////////////////////////////////////
// pair
//////////////////////////////////////////////////////////////////////

template< typename Iterator >
inline Iterator range_end( const std::pair<Iterator,Iterator>& p )
{
return p.second;
}

template< typename Iterator >
inline Iterator range_end( std::pair<Iterator,Iterator>& p )
{
return p.second;
}

您会注意到(example given in the docs 也这样做)两个版本返回相同的 Iterator 类型。

为什么我们首先需要两个重载?是为了制作 ADL工作?

最佳答案

您显然需要 const &版本因为否则你的range_begin对于 const 限定的对象将不可调用。

不太明显的是为什么你还需要 &版本,但这很简单:如果你不提供它,那么你的自定义函数比 Boost 自己的版本匹配更差。

这是一个简短的非 Boost 示例:

namespace M {
struct S { };
void f(const S &);
}

namespace N {
template <typename T>
void f(T &);

template <typename T>
void g(T &t) { f(t); }
}

void h() {
M::S s {};
N::g(s);
}

此处,在 N::g<M::S> 的实例化过程中, 一个不合格的调用 f(t)已成立,论点t类型为 M::S .有两个候选人:N::f<M::S>在同一个命名空间中,但 ADL 也找到了 M::f .前者的参数是M::S & .后者是 const M::S & .这意味着前者是更好的匹配,即使你真的想要命名空间 M 中的版本被使用。

额外的重载 M::f(S &)避免了这个问题。

关于c++ - 为什么 Boost.Range range_begin/end 自由函数对于 const 和非 const 引用都重载了?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22237138/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com