Topic 20: The first encounter with C++11--variable parameter template and C # Delegate simulation

Source: Internet
Author: User

This article was originally issued the day before yesterday, but do not know why csdn on the show, it may be I did not send, remember the wrong. Because there is no showings draft, or rewrite it, but also for the bosom friend does not leave the habit of the manuscript to make a mark.
The reason to contact C++11 is because of his whim to use C + + to simulate a C # delegate, but after trying a lot of methods and various search, know that the previous C + + is not support template overloading, it is impossible to write a variety of versions of the template to achieve the effect of the variable, if using the C + + design new thinking "In the Typelist way, I do not know can be done, even if can not achieve the desired effect, and typelist is a heavy weapon, build up more time-consuming (personal hobby, if not for the project, I will build one myself, otherwise you can use the Loki library inside). After continuing the search, we found that c++11 support the variable template! So the problem of the change of the argument even solved.
The next question is the delegate support =, + =,-= operator, so in order to let the simulated C # delegate also support these functions, so the need for an automatic expansion of the container, the list is actually good, but for the purpose of this article, the array is enough, So I first made a simple container vector (as a learning not to use vectors in the standard library):

#ifndef _vector_h_#define _vector_h_Namespace mydatastructure{Template<typename t> class Vector {Private:intcapacity;intSize_; T *vals;Private:void Copy(Constvector& v) {if(V.capacity! =0) {Vals =NewT[v.capacity]; memcpy (Vals, V.vals, v.capacity*sizeof(T)); }Else{vals = NULL;            } capacity = V.capacity;        Size_ = V.size_; }voidDestroy () {capacity = Size_ =0;if(Vals) Delete[]vals;        Vals = NULL; }voidForward_move (intStartintEndintTarg) {if(Start > End)return;if(Targ >= start)return; while(Start <= end) vals[targ++] = vals[start++]; } Public:Vector() :capacity(0),Size_(0),Vals(NULL)        {}; Vector (intcapacity): Capacity (capacity), Size_ (0) {Vals =NewT[capacity]; memset (Vals,0, capacity*sizeof(T)); } Vector (Constvector& v) {copy (v); } vector&operator= (Constvector& v) {if( This! = &v) {destroy ();            Copy (v); }return* This; }voidResizeintcapacity) {if(Capacity <=0)return; t* vs =NewT[capacity];if(Capacity <= This->capacity) {memcpy (VS, This->vals, capacity*sizeof(T)); }Else{memset (VS,0, capacity*sizeof(T)); memcpy (VS, This->vals, This->capacity*sizeof(T)); } This->capacity = capacity; This->vals = vs;if(Capacity < This->size_) Size_ = capacity; }voidPush_back (T val) {if(Capacity = =0) Resize (2);Else if(Size_ >= capacity) Resize (capacity *2);        vals[size_++] = val; }Constt&operator[](intIndexConst{returnVals[index]; } t&operator[](intIndex) {returnVals[index]; }voidClear () {Size_ =0; }BOOLEmpty () {returnSize_ = =0; }BOOL NULL()        {returnCapacity = =0; }intSize () {returnSize_; }voidEraseintIndex) {if(Index <0|| Index >= Size_)return; Forward_move (Index +1,--size_, index); }voidEraseintStartintEnd) {if(Start <0|| Start >= size_)return;if(End <0|| End >= Size_)return;if(Start > End)return; Forward_move (end +1, Size_-1, start); Size_-= (End-start +1); }intFind_first (T val) { for(inti =0; i < Size_; ++i) {if(Vals[i] = = val)returnI }return-1; }intFind_last (T val) { for(inti = size_-1; I >=0; -I.) {if(Vals[i] = = val)returnI }return-1; } vector<int> Find_all (T val) {vector<int> v; for(inti =0; i < Size_; ++i) {if(Vals[i] = = val) v.push_back (i); }returnV }    };}#endif 

To simulate a delegate action that does not contain a return value, first:

#ifndef _action_h_#define _ACTION_H_#include "Vector.h"using namespaceMydatastructure;//declaration in the same way as the argument function, plus ..., like the following, you can call types a type package,//The compiler will automatically parse the template based on the instantiation of the types contains several types, namely, which classes//type. Template<TypeName... Types>classaction{Private://Using a type package to declare a function pointer that indicates a parameter function, the key to the operator's support is it.     The //typedef keyword cannot be saved, otherwise the next typedef statement is illegal because the compiler cannot     //Recognition function is a type, using types as the type of the function parameter, the Paras is called the parameter     //several pack bar    typedef void(*function) (Types...paras);typedeffunction func; Vector<func> Funcs; Public: action&operator= (ConstFunc f) {funcs.clear ();return(* This+ = f); } action&operator+= (ConstFunc f) {funcs.push_back (f);return* This; } action&operator-= (ConstFunc f) {funcs.erase (Funcs.find_last (f));return* This; }//Implement a delegate, of course, with a C + + copy function, then the implementation () operator,    //Note parameter declaration form    void operator() (Types ... paras) {intCount = Funcs.size (); for(inti =0; I < count; i++) {//Call, tell the parameter package after ... Add, or the compiler will not recognize it,             //Formally in this form allows the compiler to unpack the parameter packageFuncs[i] (paras ...); }    }};#endif

Next, impersonate the delegate func with the return value:

#ifndef _func_h_#define _FUNC_H_#include "Vector.h"using namespaceMydatastructure;as with the variable parameter function, the argument template allows for several definite parameter declarations, but these//determined must be placed before variable parametersTemplate<TypeNameT1,TypeName... Types>classfunc{Private:typedefT1 (*function) (Types ... paras);typedeffunction func; Vector<func> Funcs; Public: func&operator= (ConstFunc f) {funcs.clear ();return(* This+ = f); } func&operator+= (ConstFunc f) {funcs.push_back (f);return* This; } func&operator-= (ConstFunc f) {funcs.erase (Funcs.find_last (f));return* This; }//Don't worry too much about the overhead of returning the vector copy constructor, the compiler's NRV optimization    //will help us, of course, in such a way as the return value of the delegate may not be reasonableVector<t1>operator() (Types ... paras) {vector<t1> v;intCount = Funcs.size (); for(inti =0; I < count;        i++) {V.push_back (Funcs[i] (paras ...)); }returnV }};#endif

After the simulation, look at the test code:

//Vector.cpp: Defines the entry point of the console application. //#include "stdafx.h"#include "Vector.h"#include "Action.h"#include "Func.h"#include <iostream>using namespaceMydatastructure;using namespace STD;voidG1 (intAintb) {cout<< A + b << endl;}voidG2 (intAintb) {cout<< A-B << endl;}voidG3 (intAintb) {cout<< A * b << endl;}voidF1 (intP) {cout<< p << Endl;}voidF2 (intP) {cout<< p*2<< Endl;}voidF3 (intP) {cout<< p *3<< Endl;}intF1 () {return 5;}intF2 () {return Ten;}intF3 () {return  the;}voidFv1 () {cout<< -<< Endl;}voidFv2 () {cout<< $<< Endl;}voidFv3 () {cout<< -<< Endl;}int_tmain (intARGC, _tchar* argv[]) {action<int> ac;    AC + = F1;    AC + = F2;    AC + = F3; Ac4);    AC-= F1; Ac5);    action<> ACV;    ACV + = Fv3;    ACV + = Fv2;    ACV + = FV1;    ACV (); action<int,int> cal;    Cal + = G1;    Cal + = G2;    Cal + = G3; Cal -, -);    Cal-= G3; Cal -, -); func<int> Fu;    Fu + = F1;    Fu + = F2;    Fu + = F3; vector<int> v = Fu (); for(inti =0; I < v.size (); ++i) {cout<< V[i] <<"'; }cout<< Endl;    Fu-= F1; v = Fu (); for(inti =0; I < v.size (); ++i) {cout<< V[i] <<"'; }cout<< Endl;return 0;}


Running results consistent with expectations, simulation success, in terms of use, in addition to no return value without parameters of the delegate is a little different, the other is the same, and the C + + simulation of the delegate can support more than 16 types, the compiler supports the number of! This way the simulation of the delegation or thanks to the c++11 added new features, otherwise it must be a lot of time to complete. It is time to learn more about c++11, this time I prefer C + + this language.

Topic 20: The first encounter with C++11--variable parameter template and C # Delegate simulation

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.