What does this template parameter mean?

Viewed 68

For the following code, what does std::uint64_t = 0 mean?

template< class T, std::uint64_t = 0 >
struct Dummy {  
   T value;
};
2 Answers

It's a non-type template parameter of type std::uint64_t with a default value of 0.

Note that the parameter is unnamed, so you can't use it directly in Dummy.

However, there are still several uses for this template parameter, e.g. you can use a different value for this parameter to select specializations of Dummy:

// specialization
template< class T>
struct Dummy<T, 42> {
   // ... 
};

Now Dummy<int> or Dummy<int, 0> will use the primary template, but Dummy<int, 42> will use the partial specialization. One of the common uses of this is in a technique called SFINAE.

Whilst @cigien's answer covers the general description of this class template:

  • two template parameters, where,
  • the first is a type template parameter, and where
  • the second a non-named non-type template parameter which has a default argument value of 0,

it may be good to point out that you can still access the non-named non-type template parameter by partially specializing the class template Dummy over a fixed type for the type template parameter, whilst adding a name for the non-type template parameter for which the partial specialization is still parameterized.

#include <cstdint>
#include <iostream>

template< class T, std::uint64_t = 0 >
struct Dummy {
   T value;
};

// Partial specialization where the remaining non-type
// template parameter is given a name which in turn can
// be used within the class template definition blueprint
// for this specialization.
template<std::uint64_t NUM>
struct Dummy<std::uint64_t, NUM> {
    // Use the named non-type template parameter to define
    // a default member initializer for the value member.
    std::uint64_t value{NUM};
};

int main() {
    std::cout 
        << Dummy<std::uint64_t, 42>{}.value  // 42 (<uint64_t, 42> specialization)
        << Dummy<std::uint32_t>{}.value      // 0  (<uint32_t, 0> specialization)
        << Dummy<std::uint32_t, 42>{}.value; // 0  (<uint32_t, 42> specialization)
                             // ^^ - template argument '42' is not used in the 
                             //      primary template (other than encoding the type)
}
Related