C++ 删除函数与ADL
我遇到了以下涉及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
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;
}