Given
template <typename T, unsigned long N>
T* begin(T (&a)[N]) {
return a;
}
template <typename T, unsigned long N>
T* end(T (&a)[N]) {
return a + N;
}
template <typename Container>
requires requires (Container c) {
{ begin(c) }
{ end(c) }
}
void f(Container& c);
void g() {
int a[4];
f(a);
}
gcc complains:
<source>: In function 'void g()':
<source>:22:8: error: cannot call function 'void f(Container&) [with
Container = int [4]]'
f(a);
^
<source>:18:6: note: constraints not satisfied
void f(Container& c);
^
<source>:18:6: note: with 'int* c'
<source>:18:6: note: the required expression 'begin(c)' would be ill-formed
<source>:18:6: note: the required expression 'end(c)' would be ill-formed
Compiler returned: 1
Looks like within the requires-expression, c decayed from int [4] to
int*. Is this warranted? I think not, the non-decayed type is used for
f() so it should be used for the constraints as well.
godbolted in https://godbolt.org/g/kqWsRj.