C++

Topic: Templates

Why do I need to add "template" and "typename" in the bodies of template definitions? 

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.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{};

Browse random answers: