Bug 90533 - [C++20] cannot redeclare telmplate function if it contains lambda expression in its declaration
Summary: [C++20] cannot redeclare telmplate function if it contains lambda expression ...
Status: RESOLVED FIXED
Alias: None
Product: gcc
Classification: Unclassified
Component: c++ (show other bugs)
Version: 9.1.0
: P3 normal
Target Milestone: 14.0
Assignee: Not yet assigned to anyone
URL:
Keywords: c++-lambda
Depends on:
Blocks: c++-lambda-decltype lambdas
  Show dependency treegraph
 
Reported: 2019-05-19 15:49 UTC by Mitsuru Kariya
Modified: 2024-04-13 07:34 UTC (History)
1 user (show)

See Also:
Host:
Target:
Build:
Known to work:
Known to fail:
Last reconfirmed: 2022-02-16 00:00:00


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Mitsuru Kariya 2019-05-19 15:49:46 UTC
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
Comment 1 Andrew Pinski 2022-02-16 01:32:05 UTC
Confirmed.
Comment 2 Andrew Pinski 2024-04-13 07:34:37 UTC
Fixed on the trunk by the recent lambda template argument patches.