template<typename T, typename... Args>
inline constexpr auto c = sizeof(T) + sizeof...(Args) > 1;
template<typename... Args>
requires c<Args...> // ok
void f1() {
}
template<typename T, typename... Args>
concept C = sizeof(T) + sizeof...(Args) > 1;
template<typename... Args>
requires C<Args...> // error: Pack expansion used as argument
// for non-pack parameter of concept.
void f2() {
}
int main() {
f1<int>(); // ok
f2<int>(); // error
}
See https://godbolt.org/z/GEWfoqdG9
CWG1430: https://cplusplus.github.io/CWG/issues/1430.html
CWG2686: https://cplusplus.github.io/CWG/issues/2686.html
Why is f1<int>() ok, but f2<int>() ill-formed?
What I want to know is not how to make the code work, but the rationale behind the restrictive rule that a concept cannot take a parameter pack as its parameters, while other temploids can.
According to n5008, the relevant statements are as follows:
13.4.1/p1 [temp.arg.general]:
The type and form of each template-argument specified in a template-id shall match the type and form specified for the corresponding parameter declared by the template in its template-parameter-list. When the parameter declared by the template is a template parameter pack (13.7.4), it will correspond to zero or more template-arguments.
Judging from the above, f2<int>() should be ok. I have also examined related sections, and found no stricter special rules for concepts and alias templates.
In addition, there have also been two related CWG issues which are still open:
CWG1430: https://cplusplus.github.io/CWG/issues/1430.html
CWG2686: https://cplusplus.github.io/CWG/issues/2686.html
So I think this is in a gray area: The C++ standard has not yet defined whether the compiler shall allow/disallow such behaviors, so the compiler can do it in its own way.
IMHO, I think both are acceptable - whether allowing or disallowing it; but I hope the committee explicitly adopts one and integrates it into the next C++ standard.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With