https://gcc.gnu.org/bugzilla/show_bug.cgi?id=123955
--- Comment #2 from Jonathan Wakely <redi at gcc dot gnu.org> ---
Reduced:
template<typename> constexpr bool is_void_v = false;
template<> constexpr bool is_void_v<void> = true;
template<typename T> concept is_void = is_void_v<T>;
template<typename T> concept D = true;
template<typename T> concept C = D<T&>;
template <typename CloseStatus>
concept InvariantClassLike =
(is_void<CloseStatus> || C<CloseStatus>);
template <typename T, typename CloseStatus>
requires InvariantClassLike<CloseStatus>
struct InvariantClass {
};
template <typename T>
requires InvariantClassLike<void>
struct InvariantClass<T, void> {
};
static_assert( InvariantClassLike<void> );
InvariantClass<int, void> iv{};
GCC isn't very helpful:
oidref.cc:24:27: error: forming reference to void
24 | InvariantClass<int, void> iv{};
| ^~
Clang trunk gives more info:
<source>:6:37: error: cannot form a reference to 'void'
6 | template<typename T> concept C = D<T&>;
| ^
<source>:10:32: note: while substituting into concept arguments here;
substitution failures not allowed in concept arguments
10 | (is_void<CloseStatus> || C<CloseStatus>);
| ^~~~~~~~~~~
<source>:18:31: note: while substituting into concept arguments here;
substitution failures not allowed in concept arguments
18 | requires InvariantClassLike<void>
| ^~~~
<source>:24:27: note: while checking constraint satisfaction for class template
partial specialization 'InvariantClass<int>' required here
24 | InvariantClass<int, void> iv{};
| ^~
<source>:24:27: note: during template argument deduction for class template
partial specialization 'InvariantClass<T, void>' [with T = int]
<source>:24:27: note: in instantiation of template class 'InvariantClass<int,
void>' requested here
1 error generated.
EDG and MSVC (and Clang 21) accept it.