The following program is incorrect,
inline constexpr auto makeFoo = [](auto const& x) {
return getFoo(x);
};
inline constexpr auto getFoo = [](int const&) {
return 1;
};
int bar() {
return makeFoo(32);
}
and reversing the definitions of makeFoo
and getFoo
makes it correct.
I understand that based on "informal" understanding of the two-phases name lookup:
makeFoo
is a generic lambda, and getFoo
in its body is invoked on an argument whose type is not known yet, so the name getFoo
can't be looked up yet;makeFoo(32)
is seen, the lambda's operator()
is intantiated with auto = int
, so the second-phase lookup for the unqualified name getFoo
happens;getFoo
, because that's the name of a lambda, i.e. an object, not of a function.Can anybody guide me to the pieces of the standard draft that "mirror" the above explanation?
I suppose [basic.lookup.unqual] and [temp.dep.res] possibly contain all it's needed to explain the case, but I can't quite stitch the pieces together.
What argument-dependent lookup does is:
Argument-dependent lookup finds all declarations of functions and function templates that [...]
Even without focusing on the details of where we're looking, argument-dependent lookup will only ever find declarations of functions and function templates. getFoo
is neither a function or function template, it is an object — so it will never be found.
So if you want getFoo
to be found, it has to be found by regular lookup — which its declaration has to precede its call.