场景:
1. 算法库的函数参数大部分都定义了一个回调, 用来作为比较判断,排序等,比如replace_if 和 sort.
2. 大部分算法库里的函数基本都需要数据结构是已排序的.
3. 使用某个函数时,如何快速写出比较函数(类型)很重要,因为快速写出比较类型可以省很多时间.比如 UnaryPredicate 和 BinaryPredicate类型.
参考:
http://en.cppreference.com/w/cpp/algorithm/replace
http://en.cppreference.com/w/cpp/algorithm/sort
http://en.cppreference.com/w/cpp/concept/Compare
需要注意的是: strict weak ordering 顺序需要遵守以下规则:
Establishes strict weak ordering relation with the following properties For all a, comp(a,a)==false If comp(a,b)==true then comp(b,a)==false if comp(a,b)==true and comp(b,c)==true then comp(a,c)==true
// test.cpp : 定义控制台应用程序的入口点。 // #include "stdafx.h" #include <algorithm> #include <math.h> #include <ctype.h> #include <assert.h> #include <Windows.h> #include <string> #include <iostream> #include <vector> //UnaryPredicate 一元比较 //template <typename T> //struct MyUnaryPredicate //{ // bool operator()(const T& t) // { // if(isdigit((unsigned char)t)) // { // return true; // } // return false; // } //}; // 除了以上声明类之外,也可以使用函数,C++函数也是一种模板类型 template <typename T> static bool MyUnaryPredicate(const T& t) { if(isdigit((unsigned char)t)) { return true; } return false; } void TestMyUnaryPredicate() { std::cout << "======TestMyUnaryPredicate=================" << std::endl; std::string str("hsdfasd1asdfas2sadfas3"); //MyUnaryPredicate<char> pre; std::replace_if(str.begin(),str.end(),MyUnaryPredicate<char>,'#'); std::cout << str << std::endl; std::wstring wstr(L"hsdfasd1asdfas2sadfas3"); //MyUnaryPredicate<wchar_t> wpre; std::replace_if(wstr.begin(),wstr.end(),MyUnaryPredicate<wchar_t>,L'#'); std::wcout << wstr << std::endl; } //BinaryPredicate, 二元比较 //template <typename T> //struct MyBinaryPredicate //{ // bool operator()(const T& val1,const T& val2) // { // if(val1 < val2) // { // return true; // } // return false; // } //}; template <typename T> bool MyBinaryPredicate(const T& val1,const T& val2) { if(val1 < val2) { return true; } return false; } void TestMyBinaryPredicate() { std::string str("asaisyfoasvzxlpqwobri"); //MyBinaryPredicate<char> up; std::sort(str.begin(),str.end(),MyBinaryPredicate<char>); std::cout << "======TestMyBinaryPredicate=================" << std::endl; std::cout << str << std::endl; } template <typename T> bool MatchInvalidCharPredicate(const T& t) { unsigned char t1 = (unsigned char)t; if(t1 <= 0x1F || t1 == 0x7F || t1 == 0x5C || t1 == 0x2F || t1 == 0x3A || t1 == 0x2A || t1 == 0x3F || t1 == 0x22 || t1 == 0x3C || t1 == 0x7C ) { return true; } return false; } template<typename C,class T> void FilterInvalidFileNameChar(T& c) { std::replace_if(c.begin(),c.end(),MatchInvalidCharPredicate<C>,L'_'); } inline char* Unicode2Ansi(const wchar_t* unicode) { int len; len = WideCharToMultiByte(CP_ACP, 0, unicode, -1, NULL, 0, NULL, NULL); char *szUtf8 = (char*)malloc(len + 1); memset(szUtf8, 0, len + 1); WideCharToMultiByte(CP_ACP, 0,unicode, -1, szUtf8, len, NULL,NULL); return szUtf8; } void TestFilterInvalidFileNameChar() { std::wstring wss(L"/as中国fasdfas?asdfas*dfa.txt"); FilterInvalidFileNameChar<wchar_t>(wss); std::cout << "======TestFilterInvalidFileNameChar=================" << std::endl; std::wcout << Unicode2Ansi(wss.c_str()) << std::endl; } int _tmain(int argc, _TCHAR* argv[]) { TestMyUnaryPredicate(); TestMyBinaryPredicate(); TestFilterInvalidFileNameChar(); system("pause"); return 0; }
输出:
======TestMyUnaryPredicate================= hsdfasd#asdfas#sadfas# hsdfasd#asdfas#sadfas# ======TestMyBinaryPredicate================= aaabfiiloopqrsssvwxyz ======TestFilterInvalidFileNameChar================= _as中国fasdfas_asdfas_dfa.txt