I’m trying meta-programming so that factorial can be computed in compile-time. Here is the 1st version:
template <int N>
struct Fac {
static const int val;
};
template <>
struct Fac<1> {
static const int val;
};
Very clear. And then I was thinking about not using const, which leads to the outside definition of the member variable. However, the first question came out:
template <int N>
struct Fac {
static int val;
};
template <>
struct Fac<1> {
static int val;
};
template <int N>
int Fac<N>::val = N * Fac<N - 1>::val;
template <> // <- error
int Fac<1>::val = 1;
The wrong is “extraneous ‘template<>’ in declaration of variable ‘val'”.
Then I found without template <>
it worked:
template <int N>
struct Fac {
static int val;
};
template <>
struct Fac<1> {
static int val;
};
template <int N>
int Fac<N>::val = N * Fac<N - 1>::val;
int Fac<1>::val = 1;
At first, I thought template <> struct Fac<1>
was redundant so I removed it, but I found then template <>
had to be added in front of Fac<1>::val
as below:
template <int N>
struct Fac {
static int val;
};
template <int N>
int Fac<N>::val = N * Fac<N - 1>::val;
template <>
int Fac<1>::val = 1;
Well, I can understand it as a full specification of the template class.
However, when adding another template parameter to prove my opinion, it went wrong again:
template <int N, int M>
struct Fac {
static int val;
};
template <int N, int M>
int Fac<N, M>::val = N * Fac<N - 1, M>::val;
template <int M> // <- error
int Fac<1, M>::val = 1;
The error was “nested name specifier ‘Fac<1, M>::’ for declaration does not refer into a class, class template or class template partial specialization”.
I am asking for a favour to explain all these phenomena.
My environment:
Apple clang version 15.0.0 (clang-1500.3.9.4)
Target: x86_64-apple-darwin23.5.0
Thread model: posix
InstalledDir: /Library/Developer/CommandLineTools/usr/bin