An example given for non-type template parameters is an array:
template <typename T, int size> // size is an integral non-type parameter
class StaticArray
{
private:
// The non-type parameter controls the size of the array
T m_array[size] {};
}
What are the options for handling negative values in the input? Using std::is_signed doesn't really apply - the template parameter is defined as signed, so the type would always be signed, whether or not the actual value provided is or not.
It looks like the implementation in std::array on my system sets the type to std::size_t, which isn't what I need in my use case. I'm hoping for something I can use with std::enable_if, where negative values are valid but have different method implementations.
I've tried the following, but that the compiler doesn't seem to be sure how to distinguish the '>' operator vs '>' as a template indication.
template<>
Iterator& operator++(std::enable_if_t<SIZE > 0>) { m_ptr++; return *this; }
template<>
Iterator& operator++(std::enable_if_t<SIZE < 0>) { m_ptr--; return *this; }
[edit]
I was unaware of constexpr-if
, which seems like a better approach but is C++17 (my original tag was C++11, but I've now added C++17).
The following is at least compiling and seems more readable than conditionally added methods, but I'm not sure if this is the recommended approach:
Iterator& operator++()
{
if constexpr (SIZE > 0)
m_ptr++;
else if constexpr (SIZE < 0)
m_ptr--;
else
static_assert(SIZE == 0, "SIZE cannot be zero.");
return *this;
}
[edit2] The syntax for enable_if/enable_if_t is unclear to me for a non-type template parameter. Both fail to compile when adding parentheses around the conditional.
With enable_if_t I get
error: argument may not have 'void' type
Iterator& operator++(std::enable_if_t<(SIZE > 0)>) { m_ptr++; return *this; }
^
With enable_if, I get
error: parameter of overloaded post-increment operator must have type 'int' (not 'std::enable_if<(2 > 0)>')
Iterator& operator++(std::enable_if<(SIZE > 0)>) { m_ptr++; return *this; }
^