Chapter 4 Nontype Template Parameters
1. Templates can have template parameters that are values rather than types
With this class, user of the stack could specify this size of the array as the maximum size needed for stack elements
template?<typename?T,?int?MAXSIZE>

class?Stack?
{
??private:
????T?elems[MAXSIZE];????????//?elements
????int?numElems;????????????//?current?number?of?elements

??public:
????Stack();??????????????????//?constructor
????void?push(T?const&);??????//?push?element
????void?pop();???????????????//?pop?element
????T?top()?const;????????????//?return?top?element

????bool?empty()?const?
{??????//?return?whether?the?stack?is?empty
????????return?numElems?==?0;
????}

????bool?full()?const?
{???????//?return?whether?the?stack?is?full
????????return?numElems?==?MAXSIZE;
????}
};

//?constructor
template?<typename?T,?int?MAXSIZE>
Stack<T,MAXSIZE>::Stack?()
??:?numElems(0)???????????????//?start?with?no?elements


{
????//?nothing?else?to?do
}

template?<typename?T,?int?MAXSIZE>
void?Stack<T,MAXSIZE>::push?(T?const&?elem)


{

????if?(numElems?==?MAXSIZE)?
{
????????throw?std::out_of_range("Stack<>::push():?stack?is?full");
????}
????elems[numElems]?=?elem;???//?append?element
????++numElems;???????????????//?increment?number?of?elements
}

template<typename?T,?int?MAXSIZE>
void?Stack<T,MAXSIZE>::pop?()


{

????if?(numElems?<=?0)?
{
????????throw?std::out_of_range("Stack<>::pop():?empty?stack");
????}
????--numElems;???????????????//?decrement?number?of?elements
}

template?<typename?T,?int?MAXSIZE>
T?Stack<T,MAXSIZE>::top?()?const


{

????if?(numElems?<=?0)?
{
????????throw?std::out_of_range("Stack<>::top():?empty?stack");
????}
????return?elems[numElems-1];??//?return?last?element
}2. You can also define nontype parameters for function templates.
template?<typename?T,?int?VAL>
T?addValue?(T?const&?x)


{
????return?x?+?VAL;
}However, according to the current standard, sets of overloaded functions cannot? be used for template parameter deduction. Thus, you have to cast to the exact type of the function template argument:
std::transform(source.begin(),source.end(),//?start?and?end?of?source
???????????????dest.begin(),//?start?of?destination
???????????????(int(*)(int?const&))addValue<int,5>);//operation
There is a proposal for the standard to fix this behavior so that the cast isn't necessary.
2. You cannot use floating-point numbers, class-type objects, and objects with internal linkage(such as string literals) as arguments for nontype template parameters