https://gcc.gnu.org/bugzilla/show_bug.cgi?id=90533
Bug ID: 90533 Summary: [C++20] cannot redeclare telmplate function if it contains lambda expression in its declaration Product: gcc Version: 9.1.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c++ Assignee: unassigned at gcc dot gnu.org Reporter: kariya_mitsuru at hotmail dot com Target Milestone: --- The sample code below should be compiled successfully in c++20 mode but gcc 9.1.0 or above generate compilation error. =========================sample code========================= template <int N> static void k(decltype([]{ return 0; }())); template <int N> static void k(decltype([]{ return 0; }())); template <int N> static void k(int) {} int main() { k<0>(0); } =======================compiler output======================= prog.cc: In function 'int main()': prog.cc:7:11: error: call of overloaded 'k<0>(int)' is ambiguous 7 | k<0>(0); | ^ prog.cc:1:30: note: candidate: 'void k(decltype (<lambda>())) [with int N = 0; decltype (<lambda>()) = int]' 1 | template <int N> static void k(decltype([]{ return 0; }())); | ^ prog.cc:2:30: note: candidate: 'void k(decltype (<lambda>())) [with int N = 0; decltype (<lambda>()) = int]' 2 | template <int N> static void k(decltype([]{ return 0; }())); | ^ prog.cc:3:30: note: candidate: 'void k(int) [with int N = 0]' 3 | template <int N> static void k(int) {} | ^ ============================================================= cf. https://wandbox.org/permlink/GRhyXXNttvOtlNxu The 1st and 2nd declarations should not contain closure type in its signature because an operand of the decltype contains no template parameter. So these three declarations should be identical. Note that the sample code above is from p0315r4 and the paper says that it is equivalent to a following code that is compiled successfully by gcc 9.1.0 or above. =========================sample code========================= struct lambda { auto operator()() const { return 0; } }; template <int N> static void k(decltype(lambda{}())); template <int N> static void k(decltype(lambda{}())); template <int N> static void k(int) {} int main() { k<0>(0); } =======================compiler output======================= cf. https://wandbox.org/permlink/jUosb2rfxR58JBbx I think the code above is bit inaccurate but a more precise version below is also compiled successfully by gcc 9.1.0 or above. =========================sample code========================= struct lambda1 { auto operator()() const { return 0; } }; struct lambda2 { auto operator()() const { return 0; } }; template <int N> static void k(decltype(lambda1{}())); template <int N> static void k(decltype(lambda2{}())); template <int N> static void k(int) {} int main() { k<0>(0); } =======================compiler output======================= cf. https://wandbox.org/permlink/kl8K4AHTPL5dL4rq [links] Wording for lambdas in unevaluated contexts http://wg21.link/p0315r4 C++2a Support in GCC https://gcc.gnu.org/projects/cxx-status.html#cxx2a