Up to C++11, the only things that could be templated were types and functions. So if you had a variable whose value was dependent on a template parameter, you had to wrap the variable in a type. Take for example this code that computes the number of bits set to 1 in a constant at compile time:
#include <cstdio>
template<unsigned N>
struct popcount;
template<>
struct popcount<0>
{
static constexpr unsigned value = 0;
};
template<unsigned N>
struct popcount
{
static constexpr unsigned value = N % 2 + popcount<(N >> 1)>::value;
};
int main()
{
// In order to actually do the computation, we have to instantiate
// a type and get the value declared inside this type.
printf("%d' n", popcount<24>::value);
}
Starting with C++14, all the types in the above code can be removed and replaced by a much more concise template variable, which also carries the intent more accurately.
#include <cstdio>
// This is a variable, whose value depends upon a template argument.
template<unsigned N>
unsigned popcount = N % 2 + popcount<(N >> 1)>;
// The variable can be specialized too!
template<>
unsigned popcount<0> = 0;
int main()
{
// Here we can use a variable to represent a value. Much more clear.
printf("%d' n", popcount<24>);
}
Note than in this specific case a constexpr function [2.1.4 ] is more suited to the task; plus it can also be called at run time.
You will probably not see many variable templates in the wild, as they are quite a niche feature. Mostly, they are used to store some domain-specific constants to the precision of a given type.