首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >删除函数与ADL

删除函数与ADL
EN

Stack Overflow用户
提问于 2017-09-20 06:26:05
回答 1查看 101关注 0票数 1

我遇到了以下涉及ADL和删除函数的令人困惑的示例:

第一个例子:

代码语言:javascript
运行
复制
namespace A
{
    struct S{};

    void f(S){cout << "adl" << endl;}
}

namespace C
{
    //void f() = delete;

    //void f (double);

    void test()
    {
        A::S arg;
        f(arg);
    }
}


int main()
{
    C::test();

    return 0;
}

正如预期的那样,A::f通过ADL被调用。在下一个示例中,C中有一个名称相同的已删除函数。

代码语言:javascript
运行
复制
namespace A
{
    struct S{};

    void f(S){cout << "adl" << endl;}
}

namespace C
{
    void f() = delete;

    //void f (double);

    void testi()
    {
        A::S arg;
        f(arg);
    }
}


int main()
{
    C::testi();

    return 0;
}

错误消息error: use of deleted function 'void C::f()'编译失败。显然,删除的函数阻止ADL版本进入重载表。现在,对于最后一个示例:除了已删除的函数外,现在还有另一个名为“未删除”的函数:

代码语言:javascript
运行
复制
namespace A
{
    struct S{};

    void f(S){cout << "adl" << endl;}
}

namespace C
{
    void f() = delete;

    void f (double);

    void testi()
    {
        A::S arg;
        f(arg);
    }
}


int main()
{
    C::testi();

    return 0;
}

运行此操作将执行f的ADL版本。因此,结论是:

  • 由于没有匹配函数,当前命名空间将导致调用ADL版本。
  • 在当前命名空间中仅删除函数将导致错误,可能是因为根本没有发现ADL版本。
  • 在当前命名空间中具有另一个未删除的函数将导致调用ADL版本.

我的问题是:这种行为是故意的吗?如果是的话,标准的哪一部分指定了这一点?

编辑:我忘记提到我用onlinegdb编译,所以使用gcc/g++。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2017-09-20 06:31:26

明确的编译器错误。引用C++标准草案(n4659) [dcl.fct.def.delete]/2

隐式或显式引用已删除函数的程序,而不是声明它的程序,是格式错误的程序。 注释:这包括隐式或显式调用函数,以及形成指向函数的指针或指针。它甚至适用于没有潜在评估的表达式中的引用。--如果函数重载,则只有通过重载解析选择该函数时,才会引用该函数。隐含的odr-使用虚拟函数本身并不构成引用. - 尾注 

重载解析不能通过ADL选择该重载。所以这个函数不应该被引用。第二个代码示例是一个格式良好的C++程序(如果缺失的包含指令被放回)。

您提到使用g++编译,请注意这个问题是GCC修正了7.2.0

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

https://stackoverflow.com/questions/46314709

复制
相关文章

相似问题

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