首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >什么是黑眼圈?

什么是黑眼圈?
EN

Stack Overflow用户
提问于 2020-07-16 05:57:15
回答 2查看 11K关注 0票数 106

使用C++20,我们现在可以更经常地阅读术语"niebloid“。

因此,我们可以在今天的2020/07/16两篇文章中提到:

谷歌也没有说出这么多的结果。最突出的可能是这里

有人能把黑斑弄得更清楚点吗?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2020-07-16 06:45:09

术语niebloid来自于Eric的名称。简单地说,它们是函数对象,它们禁止ADL (依赖于参数的查找)的发生,以便在调用std::ranges的算法时不会捕获std::ranges中的重载。

这是一条(2018年的)推文,他自己给出了这个名字的答案。埃里克在2014年写了一个文章来解释这个概念。

最好在标准文件本身中看到它的作用。

25.2.2 在本条款中的std​::​ranges命名空间中定义的实体不能通过依赖于参数的名称查找(basic.lookup.argdep)找到。当在函数调用中通过不限定(basic.lookup.unqual)名称查找查找后缀表达式时,它们会抑制依赖于参数的名称查找。 void (){使用命名空间std::range;std::vec{1,2,3};find(std(Vec),end(vec),2);// #1 } #1中的函数调用表达式调用的是std​::​ranges​::​find,而不是std​::​find,尽管(a)从begin(vec)end(vec)返回的迭代器类型可能与namespace std相关联,(b) std​::​findstd​::​ranges​::​find更专业化(temp.func.order),因为前者要求前两个参数具有相同的类型。

上面的示例关闭了ADL,因此调用直接转到std::ranges::find

让我们创建一个小示例来进一步探讨这个问题:

代码语言:javascript
复制
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;
}

来自优先选择的描述

本页中描述的类函数实体是niebloid,即:

  • 调用任何模板参数列表时都不能指定显式模板参数列表。
  • 对于依赖于参数的查找,它们都是不可见的。
  • 当一个函数调用操作符左侧的名称被正常的不限定查找找到时,它会抑制依赖于参数的查找。

Niebloid对于参数相关查找( ADL )是不可见的,因为它们是函数对象,而ADL只针对空闲函数而不是函数对象。第三点是标准示例中发生的情况:

代码语言:javascript
复制
find(begin(vec), end(vec), 2); //unqualified call to find

find()的调用是不限定的,所以当查找开始时,它会找到std::ranges::find函数对象,从而阻止ADL的发生。

搜索更多内容后,我发现了,在我看来,这是对niebloid和CPOs (定制点对象)最容易理解的解释:

..。CPO是一个对象(不是函数);它是可调用的;它是可构造的,.它是可定制的(这就是“与程序定义的类型交互”的意思);而且它是受概念约束的。 ..。 如果从上面删除形容词“可定制的、受概念约束的”,那么就有一个关闭ADL的函数对象--但不一定是自定义点。C++2a范围算法,如std::ranges::find,是这样的。任何可调用的、可构造的对象都被俗称为“niebloid”,以纪念Eric。

票数 91
EN

Stack Overflow用户

发布于 2020-08-12 20:42:58

来自优先选择

本页面中描述的类函数实体是niebloids,即:

  • 调用任何模板参数列表时都不能指定显式模板参数列表。
  • 对于依赖于参数的查找,它们都是不可见的。
  • 当一个函数调用操作符左侧的名称被正常的不限定查找找到时,它会抑制依赖于参数的查找。

在实践中,它们可以实现为函数对象,或使用特殊的编译器扩展。

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/62928396

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档