C ++ template metaprogramming 2

Source: Internet
Author: User
Tags traits

C ++ template meta-programming Chapter 2 exercise questions

2-0. Write a single dollar function add_const_ref If T is a reference type, T is returned; otherwise, T is returned.
Const &. Compile a program to test your functions. Tip: You can use boost: is_same to test the result.

This is relatively simple:

template
 
  struct add_const_ref{typedef T const& type;};template
  
   struct add_const_ref
   
    {typedef T& type;};
   
  
 
Test code:

void fun_add_const_ref(){typedef const int Cint;typedef const int& CRint;typedef int& Rint;if (boost::is_same
 
  ::type>::value){std::cout << "true\n\n";}else{std::cout << "false\n\n";}if (boost::is_same
  
   ::type>::value){std::cout << "true\n\n";}{std::cout << "false\n\n";}}
  
 



2-1. Compile a ternary metafunction replace_type It receives any Composite Type c as its first parameter,
Replace all types x in c with y:
Typedef replace_type <void *, void, int>: type t1; // int *
Typedef replace_type <
Int const * [10]
, Int const
, Long
>:: Type t2; // long * [10]
Typedef replace_type <
Char & (*) (char &)
, Char &
, Long &
>:: Type t3; // long & (*) (long &)
You can limit the type of the function to a function with less than two parameters.

This is complicated:

Solution in four steps

1. first determine whether c contains Type x

2. If there is a replacement

3. If no value is found, the meta type is returned.

4. Special template features

template
  
   struct is_same: boost::mpl::bool_
   
    {};//#1template
    
     struct is_same
     
       : boost::mpl::bool_
      
       {};//#1template
       
        struct replace_type_imp;//#2template
        
          struct replace_type{static bool const value = is_same
         
          ::value;//#3typedef typename replace_type_imp
          
           ::type type;//#4};
          
         
        
       
      
     
    
   
  
#1 determine whether two types are of the same type. If true is returned, otherwise false is returned.

# 2replace_type specific implementation, including a special situation

#3 return results with the same value

#4 return type based on vlaue Value

The following is a general implementation:

/// Special void // TC: void const *, TX: void consttemplate
  
   
Struct replace_type_imp
   
    
{Typedef typename replace_type
    
     
: Type () ;}; // special TC * // TC: int const *, TX: int consttemplate
     
      
Struct replace_type_imp
      
       
{Typedef typename replace_type
       
         : Type * type;}; // special TC & // TC: int const &, TX: int consttemplate
        
          Struct replace_type_imp
         
           {Typedef typename replace_type
          
            : Type & type ;}; // special TC [] // TC: int const [], TX: int consttemplate
           
             Struct replace_type_imp
            
              {Typedef typename replace_type
             
               : Type [] ;}; // special TC [N] // TC: int const [N], TX: int consttemplate
              
                Struct replace_type_imp
               
                 {Typedef typename replace_type
                
                  : Type [N];};
                
               
              
             
            
           
          
         
        
       
      
     
    
   
  


Special Functions

// Accept a parameter // TC: char * (*) (char *), TX: char *, TY: inttemplate
  
   
Struct replace_type_imp
   
    
{Typedef typename replace_type
    
     
: Type (typename replace_type: type); // #1 // # How can I define a function pointer at 1}; // accept two parameters // TC :: char * (*) (char *, const char *), TX: char *, TY: inttemplate
     
      
Struct replace_type_imp
      
       
{Typedef typename replace_type
       
         : Type (typename replace_type: type, typename replace_type: type) ;}; // three function templates are accepted.
        
          Struct replace_type_imp
         
           {Typedef typename replace_type
          
            : Type (typename replace_type: type, typename replace_type: type, typename replace_type: type) ;}; //... accept any more parameters
          
         
        
       
      
     
    
   
  

Value is true:

template
  
   struct replace_type_imp
   
    {typedef TY type;};
   
  

Final Test

void fun_is_same(){typedef char& (*FunPoint[])(char&);typedef char& Rchar;typedef const int v1;typedef const int v2;typedef int* v3;typedef int* (*IntPoint[])(int*);if (is_same
  
   ::value) std::cout << "same\n\n";else std::cout << "false\n\n" << std::endl;if (boost::is_same
   
    ::value) std::cout << "same\n\n";else std::cout << "false\n\n" << std::endl;typedef replace_type
    
     ::type v4;if (is_same
     
      ::value) std::cout << "same\n\n";else std::cout << "false\n\n" << std::endl;if (boost::is_same
      
       ::value) std::cout << "same\n\n";else std::cout << "false\n\n" << std::endl;typedef replace_type
       
        ::type v5;if (is_same
        
         ::value) std::cout << "same\n\n";else std::cout << "false\n\n" << std::endl;if (boost::is_same
         
          ::value) std::cout << "same\n\n";else std::cout << "false\n\n" << std::endl;typedef replace_type
          
           ::type v6;if (is_same
           
            ::value) std::cout << "same\n\n";else std::cout << "false\n\n" << std::endl;if (boost::is_same
            
             ::value) std::cout << "same\n\n";else std::cout << "false\n\n" << std::endl;}
            
           
          
         
        
       
      
     
    
   
  

2-2. boost: polymorphic_downcast
Function Template
Implement a static_cast with check version to point to Polymorphism
Downward transformation of object pointers:
Template Inline Target polymorphic_downcast (Source * x)
{
Assert (dynamic_cast (X) = x );
Return static_cast (X );
}
In the released software, assertion disappears and polymorphic_downcast can be as efficient as the simple static_cast. Use the type traits facility to compile a template implementation product so that it can receive both pointer parameters and reference parameters:
Struct A {virtual ~ A (){}};
Struct B: {};
B B;
A * a_ptr = & B; B * B _ptr = polymorphic_downcast (A_ptr); A & a_ref = B;
B & B _ref = polymorphic_downcast (A_ref );

This question is not understood and will not be done ~~~~~~


2-3. Use type traits
The Facility implements a type_descriptor class template. When it is streamed, its instance prints
The template parameter type:
Std: cout < (); // Print "char *";
Std: cout < (); // Print "longconst *&";
You can assume that the template parameters of type_descriptor are limited
Composite types constructed based on the following four integer types: char, short int, int, and long int.

This question is relatively simple, but you do not need to paste the Code directly:

template
       
        struct get_description{static std::string value;operator const char*(){return value.c_str();}};template
        
         std::string get_description
         
          ::value = "can not deduce the type";template<>std::string get_description
          
           ::value = "int";template<>std::string get_description
           
            ::value = "char";template<>std::string get_description
            
             ::value = "short";template<>std::string get_description
             
              ::value = "long";template<>std::string get_description
              
               ::value = "float";template<>std::string get_description
               
                ::value = "double";template
                
                 struct get_description
                 
                  {operator const char*(){static std::string ret = get_description
                  
                   ();ret += " const";return ret.c_str();}};template
                   
                    struct get_description
                    
                     {operator const char*(){static std::string ret = get_description
                     
                      ();ret += " *";return ret.c_str();}};template
                      
                       struct get_description
                       
                        {operator const char* (){static std::string ret = get_description
                        
                         ();ret += " &";return ret.c_str();}};
                        
                       
                      
                     
                    
                   
                  
                 
                
               
              
             
            
           
          
         
        
       
Test code:

void fun_type_descriptor(){std::cout << get_description
       
        () << std::endl;std::cout << get_description
        
         ()<< std::endl;//std::cout << get_description
         
          ()<< std::endl;}
         
        
       


2-5. Modify type_descriptor in Exercise 2-3
Template to output the type pseudo-English description, just like the cdecl Program
What the explain command does:
// Print "array of pointer to function returning pointer to char"
Std: cout <type_descriptor <char * (* [])> ();

This question is also relatively simple and can be directly written to the Code:

template
       
        struct get_description{static std::string value;operator const char*(){return value.c_str();}};template
        
         std::string get_description
         
          ::value = "can not deduce the type";template<>std::string get_description
          
           ::value = "int";template<>std::string get_description
           
            ::value = "char";template<>std::string get_description
            
             ::value = "short";template<>std::string get_description
             
              ::value = "long";template<>std::string get_description
              
               ::value = "float";template<>std::string get_description
               
                ::value = "double";template
                
                 struct get_description
                 
                  {operator const char*(){static std::string ret = get_description
                  
                   ();ret += " const";return ret.c_str();}};template
                   
                    struct get_description
                    
                     {operator const char*(){static std::string ret = get_description
                     
                      ();ret += " volatile";return ret.c_str();}};template
                      
                       struct get_description
                       
                        {operator const char*(){static std::string ret = "pointer to ";ret += get_description
                        
                         ();return ret.c_str();}};template
                         
                          struct get_description
                          
                           {operator const char* (){static std::string ret = "reference to ";ret += get_description
                           
                            ();return ret.c_str();}};template
                            
                             struct get_description
                             
                              {operator const char* (){std::cout << typeid(T).name() << "\n";static std::string ret = "array of ";ret += get_description
                              
                               ();std::cout << typeid(T).name() << "\n";return ret.c_str();}};template
                               
                                struct get_description
                                
                                 {operator const char* (){std::cout << typeid(T).name() << "\n";static std::string ret = "array of ";ret += get_description
                                 
                                  ();std::cout << typeid(T).name() << "\n";return ret.c_str();}};template
                                  
                                   struct get_description
                                   
                                    {operator const char* (){static std::string ret = "pointer to function returning ";ret += get_description
                                    
                                     ();return ret.c_str();}};template
                                     
                                      struct get_description
                                      
                                       {operator const char* (){static std::string ret = "this is a pointer function with ";ret += get_description();ret += " and it pointer to function returning ";ret += get_description
                                       
                                        ();return ret.c_str();}};template
                                        
                                         struct get_description
                                         
                                          {operator const char* (){std::cout << typeid(T).name() << "\n";static std::string ret = "pointer to function with ";ret += get_description();ret += " returning ";ret += get_description
                                          
                                           ();std::cout << typeid(T).name() << "\n";return ret.c_str();}};template
                                           
                                            struct get_description
                                            
                                             {operator const char* (){std::cout << typeid(T).name() << "\n";static std::string ret = "this is a pointer function with ";ret += get_description();ret += " and it pointer to function with ";ret += get_description();ret += " returning ";ret += get_description
                                             
                                              ();std::cout << typeid(T).name() << "\n";return ret.c_str();}};
                                             
                                            
                                           
                                          
                                         
                                        
                                       
                                      
                                     
                                    
                                   
                                  
                                 
                                
                               
                              
                             
                            
                           
                          
                         
                        
                       
                      
                     
                    
                   
                  
                 
                
               
              
             
            
           
          
         
        
       

Test code:

void fun_text_descriptor(){//std::cout << get_description
       
        () << std::endl;typedef int (*FunPoint[10])(char*);std::cout << get_description
        
         ()<< std::endl;std::cout << get_description
         
          () << std::endl;}
         
        
       

Now we have done these questions !!!!














Related Article

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.