Reputation: 1009
I came across the following confusing example involving ADL and deleted functions:
First Example:
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;
}
As expected, A::f
is called through ADL. In the next example, there is a deleted function with the same name in 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;
}
Compiling fails with the error message error: use of deleted function 'void C::f()'
. Apparently, the deleted functions stops the ADL version from getting into the overloading table. Now for the last example: In addition to the deleted function there is now another, not-deleted, function with the same name:
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;
}
Running this executes the ADL version of f
. So in conclusion:
My questions: Is this behaviour intentional? If so, which part of the standard specifies this?
Edit: I forgot to mention that I used onlinegdb for compilation, so gcc/g++ was used.
Upvotes: 1
Views: 131
Reputation: 170074
Definite compiler bug. To quote the C++ standard draft (n4659) [dcl.fct.def.delete]/2:
A program that refers to a deleted function implicitly or explicitly, other than to declare it, is ill-formed. [ Note: This includes calling the function implicitly or explicitly and forming a pointer or pointer-to-member to the function. It applies even for references in expressions that are not potentially-evaluated. If a function is overloaded, it is referenced only if the function is selected by overload resolution. The implicit odr-use of a virtual function does not, by itself, constitute a reference. — end note ]
Overload resolution cannot select that overload by ADL. So this function shouldn't be referenced. The second code sample is a well-formed C++ program (if the missing include directives are put back in).
You mentioned using g++ to compile, note that this issue is fixed in GCC 7.2.0
Upvotes: 1