C + +: Derivation of parametric types

Source: Internet
Author: User
Tags traits

STL Source Code Analysis--Houtie

    • Summarize

Although many languages now support the identification of parameter types, this feature is not supported by C + +.

But there are some tricks that we can use to make C + + automatically discriminate the parameter types.

    • Template

  We all know that in template classes and template functions We do not specify the type of the parameter, and the compiler will automatically determine the type of the parameter.

So we were wondering if we could get the type extracted from the compiler runtime?

can be implemented by inline type.

#include <iostream>using namespacestd;template<classT>structmyiter{typedef T VALUE_TYPE; //declare inline type as Value_typet*ptr; Myiter (T* p =0):p TR (p) {} T&operator*()Const{return*ptr;}}; Template<classI>TypeName I::value_type//The above line tells the compiler this type, otherwise func cannot returnfunc (I ite) {return*ite;}intMainintargcConst Char*argv[]) {Myiter<int> Ite (New int(8)); cout<< func (ITE) <<Endl; //8    return 0;}~

The Func function here can successfully extract the value_type.

But there's also a hidden trap.

This is problematic when the iterator is a native pointer, because the native pointer does not have an inline type.

This requires the template to write a biased version of this type.

1#include <iostream>2 using namespacestd;3 4Template <classT>5 structmyiter{6 typedef T VALUE_TYPE;7     //declare inline type as Value_type8t*ptr;9Myiter (t* p =0):p TR (p) {}Tent&operator*()Const{return*ptr;} One }; A  -Template <classI> - structiterator_traits_1{ the typedef typename I::value_type Value_type;  - }; - //encapsulates the myiter to get its inline type -  +Template <classT> - structIterator_traits_1<t*>{ + typedef T Value_type;  A }; at //define the type of the native pointer -  -Template <classI> -TypeName Iterator_traits_1<i>:: Value_type - //tells the compiler that the type returned by the following function - func (I ite) in{return*ite;} -  to intMainintargcConst Char*argv[]) + { -myiter<int> Ite (New int(8)); thecout << func (ITE) <<Endl; *    //returns 8 $     intA =5;Panax Notoginseng     int*b = &A; -cout << func (b) <<Endl; the     //returns 5 +     return 0; A}

Here we have the original type Myiter another layer of encapsulation, the advantage is that the following function can also be used for the native pointer.

In order to be able to use the native pointer, we also wrote a biased version.

The difference between the specialized version and the biased version is that the specialized version is only for a specific type implementation.

The partial version is for a specific set of type specificity, more general.

Here we are generating a partial version for all the native pointers.

    • About traits

  The role of traits here is very important, and its role is not only compatible with each type, but also a "type extractor".

One point to note is that in order to be compatible with traits, there must be a relevant inline type definition, which is critical in the STL iterator.

    • Iterator partial source re-column

  

1 //STL All iterator types2 structInput_iterator_tag {};3 structOutput_iterator_tag {};4 structForward_iterator_tag {}: PublicInput_iterator_tag {};5 structBidirectional_iterator_tag: PublicForward_iterator_tag {};6 structRandom_access_iterator_tag: PublicBidirectional_iterator_tag {};7 8Template <classCategory,classTclassDistance = ptrdiff_t,classPointer = t*,classReference = t&>9 structiterator{Ten typedef Category Iterator_category; One typedef T VALUE_TYPE; A typedef Distance DIFFERENCE_TYPE; - typedef Pointer Pointer; - typedef Reference Reference; the }; -  - //type extraction Machine traits -Template <classIterator> + structiterator_traits{ - typedef typename Iterator::iterator_category iterator_category; + typedef typename Iterator::value_type Value_type; A typedef typename Iterator::d ifference_type defference_type; at typedef typename Iterator::p ointer pointer; - typedef typename Iterator::reference Reference; - }; -  - //biased version for native pointers -Template <classT> in structIterator_traits<t*>{ - typedef random_access_iterator_tag Iterator_category; to typedef T VALUE_TYPE; + typedef ptrdiff_t DIFFERENCE_TYPE; -typedef t*pointer; thetypedef t&reference; * }; $ Panax Notoginseng //This function makes it easy to determine the type of an iterator (category) -Template <classIterator> theInline TypeName Iterator_traits<iterator>:: Iterator_category +Iterator_category (Constiterator&) A { thetypedef TypeName Iterator_traits<iterator>:: iterator_category category; +     returncategory (); - } $  $ //This function makes it easy to determine the distance_type of an iterator -Template <classIterator> -Inline typename Iterator_traits<iterator>::d ifference_type* theDistance_type (Constiterator&) - {Wuyi     returnStatic_cast<typename iterator_traits<iterator>::d ifference_type*> (0); the } -  Wu //This function makes it easy to determine the value_type of an iterator -Template <classIterator> AboutInline TypeName iterator_traits<iterator>::value_type* $Value_type (Constiterator&) - { -     returnStatic_cast<typename iterator_traits<iterator>::value_type*> (0); - } A  + //The following is the whole set of distance functions the //the third parameter in the two __distance function has no practical meaning, just to discriminate between the overlapping - //Surrogate Type $Template <classInputiterator> theInline iterator_traits<inputiterator>::d ifference_type the __distance (inputiterator First, Inputiterator last, Input_iterator_tag) { theIterator_traits<inputiterator>::d ifference_type n =0; the      while(Frist! =Last ) { -++first; ++N; in     } the     returnN; the } AboutTemplate <classRandomaccessiterator> theInline iterator_traits<randomaccessiterator>::d ifference_type the __distance (randomaccessiterator First, Randomaccessiteratoriterator last, the Random_access_iterator_tag) { +     returnLast-First ; - } the BayiTemplate <classInputiterator> theInline iterator_traits<inputiterator>::d ifference_type the distance (inputiterator first, inputiterator last) - { - typedef TypeName theIterator_traits<inputiterator>:: iterator_category category; the     return__distance (First, last, category ()); the}
View Code

With regard to these features, the use of STL in a large amount, to some extent, supplemented the shortcomings of C + +;

The most important thing is that these features help us to do a type of judgment when the program compiles, rather than writing a function to judge at run time.

Faster and more efficient.

C + +: Derivation of parametric types

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.