So I might have figured out that
I strongly suggest learning C++ from a book, and learning to use existing reference material, rather than trying to figure out what some code means from first principles. You're very likely to make subtle mistakes if you go by educated guesses.
The expression Factorial<N - 1>::value
is a qualified identifier.
Factorial<N - 1>
is the name of a class (an instantiation of the Factorial<int>
template with a specific value for the single parameter). This class has a data member called value
. Explicit qualification is needed since this particular value
isn't otherwise in scope. See also qualified name lookup.
You can use ::
like this for any class member: for example std::string::npos
roughly means find the data member called npos
in the class called string
in the namespace called std
.
... somehow feed/add into the 'value' variable the content of the operation performed earlier ...
there is no "earlier", this all happens during the same stage of compilation.
For example, I can manually write
struct F_0 { static const int value = 1; }
struct F_1 { static const int value = 1 * F_0::value; }
struct F_2 { static const int value = 2 * F_1::value; }
struct F_3 { static const int value = 3 * F_2::value; }
etc. etc. for as many values as I want. The templated version is effectively the same but saves a lot of typing.
Specifically, writing Factorial<3>
instantiates the template Factorial<int N>
for N=3
, which means we now have a concrete non-template class Factorial<3>
equivalent to the F_3
I wrote manually above.
The definition of this class refers to Factorial<N-1>::value
(with N-1 = 2
), so Factorial<2>
gets instantiated too. This chain of implicit instantiations continues until we reach the explicitly specialized Factorial<0>
(without that, it'd keep trying to instantiate Factorial<-1>
, Factorial<-2>
, forever until the compiler gave up and failed).