    Consider this definition of the tt(add) function template:
        verb(    template <typename Container, typename Type>
    Type add(Container const &container, Type init)
    {
        return std::accumulate(container.begin(), container.end(), init);
    })

Here tt(std::accumulate) is called using tt(container)'s tt(begin) and
tt(end) members.

    The calls tt(container.begin()) and tt(container.end()) are said to
        hi(template: statements depending on type parameters)
    em(depend on template type parameters). The compiler, not having seen
tt(container)'s interface, cannot check whether tt(container) actually
has members tt(begin) and tt(end) returning input iterators.

    On the other hand, tt(std::accumulate) itself is independent of any
template type parameter. Its em(arguments) depend on template parameters, but
the function call itself isn't. Statements in a template's body that are
independent of template type parameters are said em(not to depend on template
type parameters).

    When the compiler encounters a template definition, it verifies the
syntactic correctness of all statements not depending on template
parameters. I.e., it must have seen all class definitions, all type
definitions, all function declarations etc. that are used in those statements.
If the compiler hasn't seen the required definitions and declarations then it
will reject the template's definition. Therefore, when submitting the above
template to the compiler the tt(numeric) header file must first have been
included as this header file declares tt(std::accumulate).

    With statements depending on template parameters the compiler cannot
perform those extensive syntactic checks. It has no way to verify the
existence of a member tt(begin) for the as yet unspecified type
tt(Container). In these cases the compiler performs superficial checks,
assuming that the required members, operators and types eventually become
available.

    The location in the program's source where the template is instantiated is
        hi(template: point of instantiation) hi(point of instantiation) called
its em(point of instantiation). At the point of instantiation the compiler
deduces the actual types of the template's parameters. At that point it checks
the syntactic correctness of the template's statements that depend on template
type parameters. This implies that the compiler must have seen the required
declarations em(only at the point of instantiation).  As a
        i(rule of thumb),
    you should make sure that all required declarations (usually: header
files) have been read by the compiler at every point of instantiation of the
template. For the template's definition itself a more relaxed requirement can
be formulated. When the definition is read only the declarations required for
statements em(not) depending on the template's type parameters must have been
provided.

    On the other hand: at the point of instantiation the compiler must
em(also) have access to the template's definition. Therefore, template
definitions are commonly provided in header files: if a template must be
instantiated in some source file then the template definition, provided in a
header file (e.g., tt(template.h)) is included by the source file, so the
compiler can verify whether the template can be instantiated for the actually
used types (the same holds true for class templates, covered in the next
chapter). Here is a short example:
    itemization(
    it() The function template tt(add) is defined in tt(add.h):
        verb(    template <typename Type>
    Type add(Type const &fst, Type const &snd)
    {
        return fst + snd;
    }
        )
    it() To use it tt(fun.h) includes tt(add.h):
        verb(    #include <iostream>
    #include "add.h"
    vouid fun(size_t lhs, size_t rhs)
    {
        std::cout << add(lhs, rhs) << '\n';
    }
        )
    )

Function template definitions can be defined as inline functions
by prefixing their definitions with the keyword ti(inline). E.g,
        verb(    template <typename Type>
    inline Type add(Type const &fst, Type const &snd)
    {
        return fst + snd;
    }
       )
    As always, inline should only be used for short, one-liner function
definitions. 


