Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Overload resolution finds functions after template instantiation point

In the following code main returns 2 while I expect it to return 0 (or at least 7)

extern struct S s;
template<typename T>
constexpr int global(T&) { return 0; }

template<typename T>
//constexpr
int func(T& t) { return global(t); }

int main()
{
    return global(s) + 2*func(s) + 4*([](auto &a){return global(a);})(s);
}

static constexpr int global(S&) { return 1; }

This code is also on https://godbolt.org/z/RkkXwf

If I uncomment constexpr on func the result changes to the expected 0.

From what I understand the overload resolution should only consider functions before template instantiation point. But somehow it finds the one declared after this point for context that is neither constexpr nor generic lambda.

Why do these three lookups find different functions?

like image 515
krsch Avatar asked Oct 16 '22 13:10

krsch


1 Answers

As mentioned by n.m. in a comment, function templates may be instantiated at the end of the translation unit, see #993 and temp.point. The same paragraph says "If two different points of instantiation give a template specialization different meanings according to the one-definition rule, the program is ill-formed, no diagnostic required."

like image 196
Jeff Garrett Avatar answered Oct 18 '22 23:10

Jeff Garrett