C ++ resentment Note 7 -- function Adapter

Source: Internet
Author: User
C ++ resentment Note 7 -- function Adapter

Write a general counting function testcount and use it to count the number of spaces in the string:

#include <string>#include <iostream>using namespace std;bool TestIsspace( wchar_t ch ){    if ( ch == ' ' )        return true;    else        return false;}template <class T, class Fn >int TestCount( T p1, T p2, Fn pFn ){    int ret = 0;    for (; p1 != p2; p1 ++ )        if ( pFn(*p1) )            ret++;    return ret;}void main(){    wstring s = L"  hel  lo   ";    wchar_t buf[] = L"  hel  lo   ";    cout << TestCount(s.begin(), s.end(), TestIsspace ) << endl;    cout << TestCount(buf, buf+wcslen(buf), TestIsspace ) << endl;}

Use testcount to count the number of non-space characters. You may want to write another testisspaceneg, which calls testisspace to return the result.

bool TestIsspaceNeg( wchar_t ch ){    return !TestIsspace( ch );}

If testisspaceneg is passed in as the third parameter of testcount, isn't it all done? Although this method is very effective, it is not cumbersome. Functions similar to testisspace are more frequently used, such as library functions such as isspace, isalpha, and isdigit. Do they need to be "overwritten" every time a population is obtained? Is there a general method to retrieve the return values of each function and return them? Function pointer! In this way, you can manage a function with the same function signature. No.

bool TestGenericNeg( bool (*pFn)(wchar_t), wchar_t ch ){    return !pFn(ch);}

To generate the antifunction of testisspace, just throw the function pointer to testgenericneg.
Testgenericneg (testisspace, CH );

Well, this is an improvement. Both testisspace and library functions can be used, as long as the function signature is bool () (wchar_t. But have you found that there are more than one testgenericneg parameter, and two parameters are indispensable: one is the original function, and the other is the parameter of the original function. It is obviously not acceptable to only give testgenericneg to testcount. You must specify the function used for testgenericneg. Only testgenericneg function pointers do not work, and its information is too limited. This is also a fatal defect of function pointers. The solution to this defect is to use a function object, that is, to use a class that overload the call operator (that is, parentheses. Class Object can carry more information, including the original function pointer.

# Include <string ># include <iostream> using namespace STD; bool testisspace (wchar_t ch) {If (CH = '') return true; else return false ;} template <class T, class FN> int testcount (T P1, t P2, FN PFn) {int ret = 0; For (; P1! = P2; P1 ++) if (PFN (* P1) RET ++; return ret;} // used for other functions. The template <class FN, class T> class negclxenclose {public: fn pfn; negclxenclose (FN PFn) {This-> PFN = PFN;} bool operator () (T ch) {return! This-> PFN (CH) ;}}; void main () {wstring S = l "hello"; negclxenclose <bool (*) (wchar_t ), wchar_t> negobj (testisspace); cout <testcount (S. begin (), S. end (), negobj) <Endl; cout <testcount (S. begin (), S. end (), negclxenclose <bool (*) (wchar_t), wchar_t> (testisspace) <Endl; // For convenience, use a temporary object}

At this time, we have achieved our goal. negclxenclose is a universal and qualified anti-decoder. However, we found that when using it, we had to manually fill in the data type, such as <bool (*) (wchar_t) and wchar_t> above, which was too troublesome and a little imperfect. Is there any way for the compiler to help us fill in? The answer is: yes, a function template. When we call a function template, just like calling a common function, we never need to manually fill in the data type. This job is done by the compiler. So we can use this.
The final code can be written as follows:

# Include <string ># include <iostream> using namespace STD; bool testisspace (wchar_t ch) {If (CH = '') return true; else return false ;} template <class T, class FN> int testcount (T P1, t P2, FN PFn) {int ret = 0; For (; P1! = P2; P1 ++) if (PFN (* P1) RET ++; return ret;} template <class FN, class T> class negclxenclose {public: fn pfn; negclxenclose (FN PFn) {This-> PFN = PFN;} bool operator () (T ch) {return! This-> PFN (CH) ;}}; template <class ret, class T> negclxenclose <RET (*) (T), T> improvefn (Ret (* PFn) (t) {return negclxenclose <ERT (*) (T), T> (PFn);} void main () {wstring S = l "hello "; cout <testcount (S. begin (), S. end (), improvefn (testisspace) <Endl; // is it concise}

Is it brilliant? In fact, these tools already exist in the C ++ standard library! This is the function adapter adaptor. The following code is implemented using the Standard Library:

#include <string>#include <iostream>#include <functional> //for not1using namespace std;bool TestIsspace( wchar_t ch ){    if ( ch == ' ' )        return true;    else        return false;}template <class T, class Fn >int TestCount( T p1, T p2, Fn pFn ){    int ret = 0;    for (; p1 != p2; p1 ++ )        if ( pFn(*p1) )            ret++;    return ret;}void main(){        wstring s = L"  hel  lo   ";    cout << TestCount(s.begin(), s.end(), not1( ptr_fun(TestIsspace)) ) << endl;}

The difference is that not1 receives a function object instead of a function pointer, so we need to use ptr_fun to convert testisspace.

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.