Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why does the parameter pack not work as expected in concepts?

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.

like image 443
xmllmx Avatar asked Jan 30 '26 06:01

xmllmx


1 Answers

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.

like image 188
xmllmx Avatar answered Jan 31 '26 20:01

xmllmx