Effective C + +: Clause 42: Understanding the dual meaning of TypeName

Source: Internet
Author: User

A

In the template declaration, the two keywords of class and TypeName have exactly the same meanings

Template<class t> class Widget;template<typename t> class Widget;


Two

Template <typename c> void print2nd (const c& container) {     if (container.size () >= 2)     {         C::const _iterator iter (Container.begin ());         ++iter;         int value = *iter;         Std::cout << value;     } }
the type of ITER is c::const_iterator actually what must depend on the template parameter C. The name that appears within the template, if dependent on a template parameter, is called a subordinate name.

If the subordinate name is nested within class, it is called a nested subordinate name.
C::const_iterator is such a name nested subordinate name.

value type int. Does not depend on the name of any template parameter. Called a non-subordinate name

Nested subordinate names can cause difficulties in parsing:

Template <typename c> void print2nd (const c& container) {     c::const_iterator* x;}
This is likely to be misunderstood! Misunderstood as multiplication sign!

Before we knew C, there was no way to know if C::const_iterator was a type. And when the compiler starts parsing template print2nd, it's not yet determined what C is.

C + + has a rule that resolves this ambiguous state: if the parser encounters a nested subordinate name in the template, it assumes that the name is not a type unless you tell it to. By default, the subordinate name is not a type. In addition, there is an exception.

So the above code is not a valid C + + code. We have to tell C + + that C::const_iterator is a type. Just place the keyword typename before you close it:

Template <typename c>//This legal C + + code void print2nd (const c& container) {     if (container.size () >= 2)     { C3/>typename C::const_iterator iter (Container.begin ());         ++iter;         int value = *iter;         Std::cout << value;     } }

The exception to the rule that TypeName must be prefixed with the name of a nested subordinate type is that TypeName cannot appear in the base classes list until the nested subordinate type name is set. It is also not allowed as the base class modifier in the Member initialization list (member initialization lists) . For example:
The "typename" public is not allowed in the template <typename t> class Derived:public Base<t>::nested{//base class list:     explicit Derived (int x)         : base<t>::nested (x)//mem.init.list does not allow "typename"     {        typename base<t >::nested temp;//nested subordinate types are neither in the base class list nor in Mem.init.list,     }                                                         //As a base class modifier, add typename};

Three

Let's look at a typename example: a function template that accepts an iterator and we intend to do a copy temp for the object that the iterator refers to:

Template <typename itert>void workwithiterator (itert) {TypeName Iterator_traits<itert>::value_type temp ( *iter);}

This is an application of the standard trait class (clause 47), which is equivalent to saying "the type of object referred to by the Itert". If Itert is vector<int>::iterator,temp type is int, if Itert is the type of list<string>::iterator,temp is string. Because Std::iterator_traits<itert>::value_type is a nested subordinate type name (Value_type is nested in iterator_traits<itert> Itert is a template parameter), so you must place the typename before it.

So long you're going to want to build a typedef. For traits member names such as Value_type, it is common practice to set the TypeDef name to represent a traits member name:

Template <typename itert> void Workwithiterator (Itert) {     typedef typename std::iterator_traits<itert> :: Value_type value_type;     Value_type temp (*iter); }

Please remember:

(1) When declaring the template parameter, the Prefix keyword class and typename are interchangeable.

(2) Use the keyword typename to identify nested subordinate type names, but not in base class lists (base class column) or member initialization list (Member initial column) with its base class modifier.








Effective C + +: Clause 42: Understanding the dual meaning of TypeName

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.