[ create a new paste ] login | about

Link: http://codepad.org/ecnvop82    [ raw code | fork ]

C++, pasted on Dec 18:
//Q:  Why do I need to add "template" and "typename" in the bodies of template
//definitions?

//A:  The meaning of a name used in a template definition may depend upon the
//template parameters, in which case it cannot automatically be determined when
//the template is defined. Early implementations of templates postponed
//resolution of all names used in a template to the time of instantiation, but
//this was found to be error-prone. It made it impossible to parse template
//definitions completely because many C++ syntax rules depend on distinguishing
//between names that refer to objects or functions, names that refer to types,
//and names that refer to templates.

//Later implementations parse templates as soon as they are defined. They require
//the programmer to specify which dependent names refer to types or templates, so
//that they can parse the templates without ambiguity. Where a dependent name is
//intended to refer to a type, it must generally be prefixed by the keyword
//typename. (This is not necessary when it is used in the list of base classes of
//a class template, since only type names can be used there.) Where a dependent
//qualified name or a prefix of such a name is intended to refer to a template,
//the last component of it must be prefixed by the keyword template. Note that
//some implementations may consider names to be dependent where the standard says
//they are non-dependent, and may therefore require additional uses of typename
//and template.

// Example:

template<typename Alloc>
class container_helper
{
    typedef Alloc::value_type value_type;
        // ill-formed: Alloc::value_type is assumed to be an object or function
    typedef typename Alloc::value_type value_type;
        // OK: Alloc::pointer is properly disambiguated
    typedef Alloc::typename value_type value_type;
        // ill-formed: "typename" must precede the whole qualified name
    typedef std::pair<value_type, value_type> element_type;
        // OK: value_type is resolved in the immediate scope
    typedef typename Alloc::rebind<element_type>::other element_allocator;
        // ill-formed: Alloc::rebind is assumed to be an object or function
    typedef typename template Alloc::rebind<element_type>::other element_allocator;
        // ill-formed: "template" must precede the last component of the
        // template name
    typedef typename Alloc::template rebind<element_type>::other element_allocator;
        // OK: rebind is properly disambiguated
};

template<typename T, typename Alloc = std::allocator<T> >
class my_container : private container_helper<Alloc>::element_allocator
        // OK: container_helper<Alloc>::element_allocator cannot be resolved
        // but base names are assumed to be type names
{
};


Create a new paste based on this one


Comments: