https://gcc.gnu.org/bugzilla/show_bug.cgi?id=125299

            Bug ID: 125299
           Summary: Using compound requirement in default argument for
                    non-type template parameter fails to compile
           Product: gcc
           Version: 16.1.0
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: c++
          Assignee: unassigned at gcc dot gnu.org
          Reporter: deltastruct47 at gmail dot com
  Target Milestone: ---

GCC fails to compile a requires-expression containing a compound requirement
when it is used directly as a default argument for a non-type template
parameter.

```
#include <concepts>

template<bool B = requires(int x){ { x } -> std::same_as<int>; }>
int i;

int main(){}
```

```
<source>:3:50: error: wrong number of template arguments (1, should be 2)
    3 | template<bool B = requires(int x){ { x } -> std::same_as<int>; }>
      |                                                  ^~~~~~~~~~~~
In file included from <source>:1:
/cefs/38/383ad2f84cbd57a52fd68bbe_consolidated/compilers_c++_x86_gcc_16.1.0/include/c++/16.1.0/concepts:64:13:
note: provided for 'template<class _Tp, class _Up> concept std::same_as'
   64 |     concept same_as
      |             ^~~~~~~
<source>:3:45: error: expected type-specifier
    3 | template<bool B = requires(int x){ { x } -> std::same_as<int>; }>
      |                                             ^~~
<source>:3:50: error: wrong number of template arguments (1, should be 2)
    3 | template<bool B = requires(int x){ { x } -> std::same_as<int>; }>
      |                                                  ^~~~~~~~~~~~
/cefs/38/383ad2f84cbd57a52fd68bbe_consolidated/compilers_c++_x86_gcc_16.1.0/include/c++/16.1.0/concepts:64:13:
note: provided for 'template<class _Tp, class _Up> concept std::same_as'
   64 |     concept same_as
      |             ^~~~~~~
```

According to the C++20 standard, the form "{ E } -> Concept<Args...>;" should
be equivalent to "E; Concept<decltype((E)), Args...>;". However, in this
specific context, the compiler seems to evaluate it as "E; Concept<Args...>;"
(or similar), omitting the implicit first argument. This leads to a "wrong
number of template arguments" error.

This bug exists since GCC 12.1.0.

Workaround:
```
concept C = requires(int x){ { x } -> std::same_as<int>; };
template<bool B = C>
int a;

constexpr bool L = requires(int x){ { x } -> std::same_as<int>; };
template<bool B = L>
int b;

template<bool B = []{ return requires(int x){ { x } -> std::same_as<int>; };
}()>
int c;
```

Godbolt playground: https://godbolt.org/z/zET9sxve9
  • [Bug c++/125299] New: Using co... deltastruct47 at gmail dot com via Gcc-bugs

Reply via email to