使用 C++20,我们现在可以在 cppreference 中更频繁地阅读术语“niebloid”。
在 SO 上,我们今天可以找到 2020/07/16 2 篇提到它的文章:
谷歌也没有吐出那么多结果。最突出的可能是 here 。
有人可以更多地了解 niebloids 吗?
最佳答案
术语 niebloid 来自 Eric Niebler 的名字 。简而言之,它们是禁止 ADL(参数相关查找)发生的函数对象,以便在调用 std::
中的算法时不会拾取 std::ranges
中的重载。
这是一条推文(来自 2018 年)和来自 Eric himself 的回答建议名称。 Eric 在 2014 年写了一篇 article 来解释这个概念。
在 standard document itself 中可以最好地看到它:
上面的示例关闭了 ADL,因此调用直接转到 std::ranges::find
。
让我们创建一个小例子来进一步探索:
namespace mystd
{
class B{};
class A{};
template<typename T>
void swap(T &a, T &b)
{
std::cout << "mystd::swap\n";
}
}
namespace sx
{
namespace impl {
//our functor, the niebloid
struct __swap {
template<typename R, typename = std::enable_if_t< std::is_same<R, mystd::A>::value > >
void operator()(R &a, R &b) const
{
std::cout << "in sx::swap()\n";
// swap(a, b);
}
};
}
inline constexpr impl::__swap swap{};
}
int main()
{
mystd::B a, b;
swap(a, b); // calls mystd::swap()
using namespace sx;
mystd::A c, d;
swap(c, d); //No ADL!, calls sx::swap!
return 0;
}
来自 cppreference 的描述:Niebloid 对参数依赖查找 (ADL) 不可见,因为它们是函数对象,并且 ADL 仅针对自由函数而不是函数对象执行。第三点是标准示例中发生的事情:
find(begin(vec), end(vec), 2); //unqualified call to find
对 find()
的调用是不合格的,因此当查找开始时,它会找到 std::ranges::find
函数对象,从而阻止 ADL 发生。搜索更多,我找到了 this,在我看来,这是对 niebloids 和 CPO(自定义点对象)最容易理解的解释:
关于c++ - 什么是尼布洛德?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/62928396/