Description
Full name of submitter (unless configured in github; will be published with the issue): Hubert Tong
Reference (section label): [temp.over.link]
Link to reflector thread (if any): N/A
Issue description:
It is unclear whether the resolution of CWG 1321 meant to cover cases where ADL is not in scope (e.g., because lookup found a callable object or a block-scope extern declaration). For example, the wording says that the following should compile because the use of C
in N::f
subsumes the use of C
in M::f
despite the fact that the use of C
in M::f
can never be satisfied (whereas the use of C
in N::f
can be satisfied). That is, the wording allows for using the contradictory logic that something false is implied by something true.
There is implementation divergence (Clang, GCC, and MSVC reject; EDG accepts); https://godbolt.org/z/79YfEP6Wr:
template <typename ...T>
struct Blob : T ... {
using T::operator() ...;
};
template <typename T> constexpr bool IsInt = false;
template <> constexpr bool IsInt<int> = true;
template <typename T> concept C = IsInt<T>;
namespace N {
constexpr auto f() {
int f(int);
return [](auto x) requires C<decltype(f(x))> { return true; };
}
}
namespace M {
constexpr auto f() {
short f(int);
return [](auto x) requires C<decltype(f(x))> || (sizeof(x) == 4) {};
}
}
template <typename ...T>
constexpr Blob<T ...> blobber(T ...) { return {}; }
static_assert(blobber(N::f(), M::f())(0));
Additionally, a call with a parenthesized unqualified-id as the callee is not considered a "dependent call" (https://wg21.link/temp.dep.general#2). The leaves us with the original problem of Core Issue 1321 for such call expressions.
Suggested resolution:
Retain the resolution of CWG 1321 for ADL cases.
Use the unique result of name lookup for the non-function case.
Some "invention here":
Use the results of name lookup (plus any dependent using declarations) in the class scope case.
Use the set of block scope declarations (including using declarations) in the block scope case.
Where the operand is a parenthesized unqualified-id not matching the above cases, use the namespace scope (i.e., ignoring the specific declarations and any using directives) in addition to the name.