C++ 删除函数与ADL

C++ 删除函数与ADL,c++,overloading,argument-dependent-lookup,C++,Overloading,Argument Dependent Lookup,我遇到了以下涉及ADL和已删除函数的混淆示例: 第一个例子: 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 m

我遇到了以下涉及ADL和已删除函数的混淆示例:

第一个例子:

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;
}
编译失败,出现错误消息
错误:使用已删除的函数“void C::f()”
。显然,删除的函数会阻止ADL版本进入重载表。现在来看最后一个示例:除了已删除的函数外,现在还有另一个同名函数,而不是已删除的函数:

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;
}
名称空间A
{
结构S{};

空f(s){cOUT> p>限定编译器bug。引用C++标准草案(N4665):

隐式或显式引用已删除函数的程序, 除了声明它,它的格式是错误的[ 注意:这包括打电话 隐式或显式函数,并形成指针或 指向函数成员的指针。它甚至适用于中的引用 未进行潜在计算的表达式。如果函数 重载,仅当用户选择函数时才引用该函数 重载解析。虚拟函数的隐式odr使用 其本身并不构成参考。 — 尾注 ]

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



您提到使用g++进行编译,请注意,这个问题是

我刚刚意识到我的系统中使用了g++5.4.1 c++14example@LcdDrm-您可以使用并按GCC版本执行二进制搜索,以准确了解修复的时间,如果您愿意:)GCC 6.3失败,GCC 7.1正常工作。MS Visual Studio编译器也正常工作
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;
}