I've got this code:
#include <iostream>
template <typename num_t, num_t num>
struct factorial {
consteval operator num_t() { return num * factorial<num_t, num - 1>{}; }
};
template <typename num_t>
struct factorial<num_t, 2> {
consteval operator char() { return 2; }
};
int main() {
std::cout << factorial<unsigned long long, 20>{} << '\n';
}
Clang gives me an error under 2 in struct factorial<num_t, 2>. The message is:
error: non-type template argument specializes a template parameter with dependent type 'num_t'
I've looked around a bit and it seems to be because of this part in the standard:
Paragraph [temp.class.spec] 14.5.5/8 of the standard:
The type of a template parameter corresponding to a specialized non-type argument shall not be dependent on a parameter of the specialization. [ Example:
template <class T, T t> struct C {};
template <class T> struct C<T, 1>; // error
template< int X, int (*array_ptr)[X] > class A {};
int array[5];
template< int X > class A<X,&array> { }; // error
—end example ]
Can someone explain the reasoning behind this section of the standard. It seems to me that they're simply getting in my way. What practical (or even theoretical) value comes with this rule?
Also, I'm more than a little confused about the wording that's being used. Can someone who understands maybe translate it into a more easy-to-understand phrasing?