Chapter 5 Technical Basis: 5.1 Keyword typename

Chapter 5:Tricky Basics

Chapter 5 Basic Skills

 

This chapter covers some further basic aspects of templates that are relevant to the practical use of templates: an additional use of the typename keyword, defining member functions and nested classes as templates, template template parameters, zero initialization, and some details about using string literals as arguments for function templates. These aspects can be tricky at times, but every day-to-day programmer should have heard of them.

This chapter gives some more in-depth basic knowledge of templates, which are closely related to the actual application of templates. Including another usage of the keyword typename, defining member function nested classes as templates, template template parameters, zero initialization, and using string literals as the actual parameters of function templates. detail. Although these techniques are highly technical, every daily C ++ programmer should have heard about them.

5.1 Keyword typename

5.1 Keyword typename

 

The keyword typename was introduced during the standardization of C++ to clarify that an identifier inside a template is a type. Consider the following example:

In the C ++ standardization process, the keyword typename was introduced to illustrate that the identifier inside the template is a type. Consider the following example:

template<typename T>
class MyClass {
public:
    …
    void foo() {
        typename T::SubType* ptr;
    }
};

Here, the second typename is used to clarify that SubType is a type defined within class T. Thus, ptr is a pointer to the type T::SubType.

In the above example, the second typename is used to illustrate: SubType is a type defined inside class T. Therefore, ptr is a pointer to type T :: SubType.

Without typename, SubType would be assumed to be a nontype member (e.g., a static data member or an enumerator constant). As a result, the expression

If you do not use typename, SubType will be considered as a non-type member (for example, a static member variable or enumeration constant). As a result, the following expression will

T::SubType* ptr;

would be a multiplication of the static SubType member of class T with ptr, which is not an error, because for some instantiations of MyClass<> this could be valid code.

It will be considered as the product of the static members SubType and ptr of class T. This is not an error, because for some instance of MyClass <>, this may be valid code.

In general, typename has to be used whenever a name that depends on a template parameter is a type. This is discussed in detail in Section 13.3.2 on page 228.

In general, when a name that depends on template parameters is a type, you should use typename. We will discuss this issue in detail in Section 13.3.2 on page 228.

One application of typename is the declaration to iterators of standard containers in generic code:

A classic application of typename is to declare iterators of STL containers with common code:

#include <iostream> // print elements of an STL container 
template <typename T> void printcoll (T const & coll) 
{ 
    typename T :: const_iterator pos; // iterator for iterating coll 
    typename T :: const_iterator end ( coll.end ()); // End position for (pos = coll.begin (); pos! = end; ++ pos) { 
        std :: cout << * pos << ' ' ; 
    } 
    std :: cout < < ' \ n ' ; 
}



    
     
    

In this function template, the call parameter is an standard container of type T. To iterate over all elements of the container, the iterator type of the container is used, which is declared as type const_iterator inside each standard container class:

In this function template, the formal parameter is a T-type STL container. In order to iterate all the elements in the container, we use the iterator type: and in each STL container class, iterator type const_iterator is declared:

class stlcontainer {
 public :
     using iterator =…; // An iterator that can be read / written / accessed 
    using const_iterator =…; // Iterator of read-only type 

};

Thus, to access type const_iterator of template type T, you have to qualify it with a leading typename:

Therefore, in order to access the const_iterator iterator with template type T. You need to use typename to qualify at the beginning of the declaration:

typename T::const_iterator pos;

See Section 13.3.2 on page 228 for more details about the need for typename until C++17.

For more details on the typename required before C ++ 17, please refer to section 13.3.2 on page 228.

 

Note that C++20 will probably remove the need for typename in many common cases (see Section 17.1 on page 354 for details).

Note that in many common situations, C ++ 20 may eliminate the need for typename (for details, see section 17.1 on page 354)

Guess you like

Origin www.cnblogs.com/5iedu/p/12731308.html
Recommended