我遇到了以下涉及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;
}
正如预期的那样,A::f
通过ADL被调用。在下一个示例中,C
中有一个名称相同的已删除函数。
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版本进入重载表。现在,对于最后一个示例:除了已删除的函数外,现在还有另一个名为“未删除”的函数:
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版本。因此,结论是:
我的问题是:这种行为是故意的吗?如果是的话,标准的哪一部分指定了这一点?
编辑:我忘记提到我用onlinegdb编译,所以使用gcc/g++。
发布于 2017-09-20 06:31:26
明确的编译器错误。引用C++标准草案(n4659) [dcl.fct.def.delete]/2
隐式或显式引用已删除函数的程序,而不是声明它的程序,是格式错误的程序。 注释:这包括隐式或显式调用函数,以及形成指向函数的指针或指针。它甚至适用于没有潜在评估的表达式中的引用。--如果函数重载,则只有通过重载解析选择该函数时,才会引用该函数。隐含的odr-使用虚拟函数本身并不构成引用. - 尾注
重载解析不能通过ADL选择该重载。所以这个函数不应该被引用。第二个代码示例是一个格式良好的C++程序(如果缺失的包含指令被放回)。
您提到使用g++编译,请注意这个问题是GCC修正了7.2.0。
https://stackoverflow.com/questions/46314709
复制相似问题