C++ 11笔记
2017-01-11 09:08
295 查看
20161118添加:
http://www.cnblogs.com/haippy/p/3237213.html
https://my.oschina.net/shou1156226/blog/802859
深入应用C++ 11:代码优化与工程级应用
祁宇 著
2015.5出版
技术博客http://www.cnblogs.com/qicosmos/
本书示例代码需要支持C++ 11的编译器:
Windows:Visual Studio 2013。
Linux:GCC 4.8+或者Clang 3.4。
由于少数代码用到了boost库,还需要编译boost 1.53或更新的boost库。
chap1 使用C++ 11让程序更简洁、更现代
1.1类型推导
C++ 11引入了auto和decltype关键字实现类型推导。
1.1.1 auto类型推导
auto并不能代表一个实际的类型声明,只是一个类型声明的占位符。
使用auto声明的变量必须马上初始化,以让编译器推断出它的实际类型,并在编译时将auto占位符替换为真正的类型。
非static的局部变量默认就是具有自动存储期的。
3.auto的限制
auto是不能用于函数参数的。
4.什么时候用auto
auto简化STL迭代器(iterator)变量的定义
注意:auto是一个很强大的工具,但不加选择地随意使用auto,会带来代码可读性和可维护性的严重下降。因此,在使用auto的时候,一定要权衡好它带来的价值和相应的损失。
1.1.2 decltype关键字
若仅希望得到类型,而不需要(或不能)定义变量的时候应该怎么办呢?
C++ 11新增了decltype关键字,用来在编译时推导出一个表达式的类型。
1.1.3 返回类型后置语法——auto和decltype的综合使用
20170331添加:
5.7右值引用
右值引用的目的是为了实现“移动语义”和“完美转发”。
将普通的引用定义为Type&,那么右值引用的写法则是Type&&,通过std::move函数,可以将左值转换为右值引用,move可理解为static_cast<T&&><obj>。
C++ 11有一个定义:“基于安全的原因,具名参数将不被认定为右值,即便是右值引用,必须使用move来获取右值”。
5.7.2移动语义
移动是为了消除不必要的对象复制,为提高效率而存在的。
VS的DEBUG模式默认没有开启RVO。
在C++ 11之前,使用const A&也可以将函数内的变量取出,但由于是const引用,所以并不能对变量进行操作,而非const的右值引用则没有该限制。
3种构造方法:
默认复制构造(浅拷贝)、复制构造(深拷贝)、移动构造
5.7.3完美转发
完美转发是为了能更简洁明确地定义泛型函数——将一组参数原封不动地传给另一个函数。原封不动指的是参数数值和类型不变,参数的const属性不变。
C++ 11定义的T&&推导规则是,右值实参为右值引用,左值实参为左值引用,参数属性不变。
5.8显示虚函数重写
override和final并不是关键字,只有在特定的位置才有特殊含义,在其他地方仍可当变量来使用。为了保存向后兼容,override是选择性的。
20170409添加:
// 20170409.cpp : 定义控制台应用程序的入口点。
//
#include "stdafx.h"
// VS2012编译
#include <set>
#include <iostream>
template <typename ObType, typename BinaryFunction>
bool isGroup12(const std::set<ObType> & S, BinaryFunction & op)
{
/*
isGroup returns true or false depending on whether the set S
along with the operator op is a group in the Algebraic sense.
That is, S is a group if and only if all the 4 following
conditions are true:
(1) If a, b in S, then a op b in S
(2) If a, b, c in S, then (a + b) + c = a + (b + c)
(3) There is an element 0 in S such that a + 0 = 0 + a for all a in S
(4) If a in S, then there is a b in S such that a + b = b + a = 0
*/
typename std::set<ObType>::const_iterator beg(S.cbegin()), offend(S.cend());
bool noProblems = true;
for (std::set<ObType>::const_iterator ia = beg; ia != offend && noProblems; ++ia)
{
for (std::set<ObType>::const_iterator ib = beg; ib != offend && noProblems; ++ib)
{
// ---------- (1) --------------
if (S.count(op(*ia, *ib)) == 0)
noProblems = false;
// -----------------------------
for (std::set<ObType>::const_iterator ic = beg; ic != offend && noProblems; ++ic)
{
// ---------- (2) -------------
//is wrong
//if (((*ia + *ib) + *ic) != (*ia + (*ib + *ic)))
// noProblems = false;
if ( op( op(*ia,*ib), *ic) != op( *ia, op( *ib, *ic)))
noProblems = false;
// ----------------------------
}
}
}
return noProblems;
}
template <typename ObType, typename BinaryFunction>
bool isGroup3( const std::set<ObType> & S, BinaryFunction & op)
{
// ... important define BinaryFunction as taking const args !
typename std::set<ObType>::const_iterator beg(S.cbegin()), offend(S.cend());
for (std::set<ObType>::const_iterator ia = beg; ia != offend; ++ia)
{
// ---------- (3) -------------
/* let e be an *ia */
ObType e = *ia;
bool isGroup = true;
for ( auto ia2 : S) {
if( op(ia2, e) != ia2 || op( e, ia2) != ia2) {
isGroup = false;
break;
}
// identity found, set e_ in class to e and return
if( isGroup) {
// e_ = e;
return true;
}
}
}
/* identity not found, this is not a group */
return false;
}
template <typename T>
class Plus
{
public:
T operator() (const T & x, const T & y) { return x + y; };
};
int main()
{
#if 1
int a1[]={0, 1, -1};
int n1=sizeof(a1)/sizeof(int);
std::set<int> S1(a1,a1+n1);
int a2[]={0};
int n2=sizeof(a2)/sizeof(int);
std::set<int> S2(a2,a2+n2);
#else
std::set<int> S1 = { 0, 1, -1 };//这种写法在VS2013以后支持
std::set<int> S2 = { 0 };//这种写法在VS2013以后支持
#endif
class Plus<int> p;
std::cout << isGroup12(S1, p)<<std::endl;
std::cout << isGroup3(S1, p)<<std::endl;
system("pause");
return 0;
}
20170413添加:
使用STL通用算法find_if()在list中搜索对象
这是find()的一个更强大的版本。这个例子演示了find_if(),它接收一个函数对象的参数作为参数,并使用它来做更复杂的评价对象是否和给出的查找条件相符。
// VS2012编译
#include <iostream>
#include <string>
#include <list>
#include <vector>
#include <algorithm>
#include <functional>//greater
using namespace std;
// 类比较,重载了()操作符
class personIsIn1492
{
public:
bool operator()(string& personRecord)
{
return personRecord.substr(0,4)=="1492";//第二个参数是要截的长度,不是截取结束的位置
}
};
void Test1()
{
list<string> persons;
persons.push_back("1487迪亚士");
persons.push_back("1492.10.12哥伦布 国庆日");
persons.push_back("1519麦哲伦");
persons.push_back("1649.1查理二世");
persons.push_back("1774中原王伦起义");
#if 1
/*
捕获列表捕获的是调用该表达式函数内的局部非静态变量,对于那些函数内的静态变量和定义在函数外的变量,Lambda表达式可以直接使用。
下面Lambda表达式中捕获了变量str,返回类型是bool。
编译器在解释Lambda表达式时,会解释成一个未命名类的未命名对象,该类包含了一个重载函数调用操作符的函数,如果捕获列表中包含有值捕获参数时,那么该类中会有一个相对应的成员参数
*/
string str="1492";
list<string>::iterator personIterator = find_if (persons.begin(), persons.end(),[str](string& personRecord)->bool{
if(personRecord.substr(0,4)==str)return true;
return false;
});
#else
// 使用重载了()操作符类对象比较
list<string>::iterator personIterator = find_if (persons.begin(), persons.end(),personIsIn1492());
#endif
if (personIterator==persons.end()) {
cout << "person not found in list" << endl;
}
else {
cout << *personIterator << endl;
}
}
class Grade
{
public:
Grade(int id,string name,int score)
{
ID=id;
Name=name;
Score=score;
}
int ID;
string Name;
int Score;
};
//针对Grade的vector对象进行排序
//定义函数对象用来排序
class sort_Grade
{
//函数对象的最大好处是可以内联,效率极高
public:
sort_Grade(){}
bool operator()(Grade X,Grade Y)const
{
//return X.Score<Y.Score;//按成绩的升序排
return X.Score>Y.Score;//按成绩的降序排
}
};
void Test2()
{
vector<Grade> finalGrade;
finalGrade.push_back(Grade(1,"A",56));
finalGrade.push_back(Grade(2,"B",57));
finalGrade.push_back(Grade(3,"C",58));
//当定义了用于排序的函数对象后就可以直接调用sort算法进行排序了
#if 1
//sort中使用Lambda表达式:
sort(finalGrade.begin(),finalGrade.end(),[](Grade X,Grade Y)->bool{
//return X.Score<Y.Score;//按成绩的升序排
return X.Score>Y.Score;//按成绩的降序排
});
#else
//排序,根据函数对象,函数对象的最大好处是可以内联,效率极高
sort(finalGrade.begin(),finalGrade.end(),sort_Grade());
#endif
int a=0;
}
void Test3()
{
int a[10]={0};
int N=5;
vector<int> b;
for(int i=0;i<N;i++)
{
cin>>a[i];
b.push_back(a[i]);
}
#if 1
//sort中使用Lambda表达式:
sort(a,a+N,[](int i,int j)->bool{
return (i>j);//降序排
});
sort(b.begin(),b.end(),[](int i,int j)->bool{
return (i<j);//升序排
});
#else
sort(a,a+N,greater<int>());//降序排列
sort(b.begin(),b.end());//升序排列
#endif
for(int i=0;i<N;i++)
cout<<a[i]<<" ";
cout<<endl;
for(int i=0;i<N;i++)
cout<<b[i]<<" ";
}
// 函数比较,例如带金牌的麻将牌排序
bool func(int i,int j,bool less,int a)
{
//a放在最左边
if(i==a)
return true;
if(j==a)
return false;
return less?(i<j):(i>j);//升序:降序
}
void Test4()
{
vector<int>::iterator Iter;
vector<int> the_vector;
int temp;
for( int i = 0; i < 5; i++ )
{
cin>>temp;
the_vector.push_back(temp);//vector无push_front方法
}
#if 1
// bind函数,用于函数绑定的模版,它可以指定函数中的部分参数,也可以是全部参数
sort(the_vector.begin(),the_vector.end(),bind(func,placeholders::_1,placeholders::_2,true,4));//升序排列,4放在最左边
//sort(the_vector.begin(),the_vector.end(),bind(func,placeholders::_1,placeholders::_2,false,4));//降序排列,4放在最左边
#else
sort(the_vector.begin(),the_vector.end(),less<int>());//升序排列
//sort(the_vector.begin(),the_vector.end(),greater<int>());//降序排列
#endif
cout<<"the_vector=";
for(Iter=the_vector.begin();Iter!=the_vector.end();Iter++)
cout<< " "<<*Iter;
cout<<endl;
}
void Test5()
{
//string str="abcdadcdefdde!@234";
string str="ABCDADCDEFDDE!@234";
#if 0
transform(str.begin(),str.end(),str.begin(),[](char ch)->char{return ch+1;});
#else
// 将字符串变成大写
//transform(str.begin(),str.end(),str.begin(),toupper);
// 将所有的字符变成小写
transform(str.begin(),str.end(),str.begin(),tolower);
#endif
cout<<str;
}
int main(int argc, char* argv[])
{
Test1();
Test2();
//Test3();
Test4();
Test5();
system("pause");
return 0;
}
20170417添加:
//VS2012编译
#include<cstdlib>
#include<functional>
#include<iostream>
#include<string>
using namespace std;
//ToInt成员函数的返回值与WinGDI.h的RGB宏或VB6的RGB函数值是不一致的,请不要混淆
//typedef unsigned long D3DCOLOR;
class Color
{
public:
int mRed;
int mGreen;
int mBlue;
int mAlpha;//255表示完全不透明
static Color Black;
static Color White;
static Color Empty;
public:
//缺省构造函数
Color():mRed(0),mGreen(0),mBlue(0),mAlpha(255){}
Color(int theRed,int theGreen,int theBlue,int theAlpha=0xFF):mRed(theRed),mGreen(theGreen),mBlue(theBlue),mAlpha(theAlpha){}
//拷贝构造函数
Color(const Color& c):mRed(c.mRed),mGreen(c.mGreen),mBlue(c.mBlue),mAlpha(c.mAlpha){}
//操作符重载
int& operator[](int theIdx);
int operator[](int theIdx)const;
Color& operator=(const Color& c){mRed=c.mRed;mGreen=c.mGreen;mBlue=c.mBlue;mAlpha=c.mAlpha;return *this;}
//inline函数
int GetRed()const{return mRed;}
int GetGreen()const{return mGreen;}
int GetBlue()const{return mBlue;}
int GetAlpha()const{return mAlpha;}
unsigned long ToInt()const{return (mAlpha<<24)|(mRed<<16)|(mGreen<<8)|(mBlue);}//返回值与D3DCOLOR_ARGB宏是一致的
unsigned long ToWinRGBInt()const{return (0<<24)|(mBlue<<16)|(mGreen<<8)|(mRed);}
static Color& WinRGBToColor(unsigned long lng);
static unsigned char GetRedValue(unsigned long lng);
static unsigned char GetGreenValue(unsigned long lng);
static unsigned char GetBlueValue(unsigned long lng);
friend ostream& operator<<(ostream& os,const Color& c);//put-to操作符<<
};
Color& Color::WinRGBToColor(unsigned long lng)
{
unsigned char b[10]={0};
//unsigned char b[4]={0};
memcpy(&b[0],&lng,4);
return Color(b[0],b[1],b[2],b[3]);
//int i[4]={0};
//i[0]=b[0];
//i[1]=b[1];
//i[2]=b[2];
//i[3]=b[3];
//return Color(i[0],i[1],i[2],i[3]);
//return Color((int)b[0],(int)b[1],(int)b[2],(int)b[3]);
}
unsigned char Color::GetRedValue(unsigned long lng)
{
return (unsigned char)(lng);
}
unsigned char Color::GetGreenValue(unsigned long lng)
{
return (unsigned char)(unsigned short((lng)>>8));
}
unsigned char Color::GetBlueValue(unsigned long lng)
{
return (unsigned char)((lng)>>16);
}
ostream& operator<<(ostream& os,const Color& c)
{
os<<"ARGB:"<<c.mAlpha<<","<<c.mRed<<","<<c.mGreen<<","<<c.mBlue;
return os;
}
int& Color::operator[](int theIdx)
{
static int aJunk=0;
switch(theIdx)
{
case 0:return mRed;
case 1:return mGreen;
case 2:return mBlue;
case 3:return mAlpha;
default:return aJunk;
}
}
int Color::operator[](int theIdx)const
{
switch(theIdx)
{
case 0:return mRed;
case 1:return mGreen;
case 2:return mBlue;
case 3:return mAlpha;
default:return 0;
}
}
//ARGB:255,255,0,0
//4294901760
//ARGB:0,255,0,0
//16711680
//ARGB:0,0,0,255
//255
//ARGB:255,0,0,255
//4278190335
//16711680
void Test7()
{
//const Color &theColor=Color(255,0,0);
//const Color &theColor=Color(255,0,0,255);
//const Color &theColor=Color(255,0,0,0);
//const Color &theColor=Color(0,0,255,0);//blue
const Color &theColor=Color(0,0,255,255);//blue
cout<<theColor<<endl;
#if 1
// function存放类的公有成员函数,使用bind绑定成员函数和对象指针,使用placeholders::_1~placeholders::_20占位符来表示函数的参数数量
function<unsigned long()> mf1=bind(&Color::ToInt,theColor);
function<unsigned long()> mf2=bind(&Color::ToWinRGBInt,theColor);
cout<<mf1()<<endl;
cout<<mf2()<<endl;
// function存放静态函数
function<Color(unsigned long)> smf1=Color::WinRGBToColor;
Color c=smf1(16761798);
cout<<c<<endl;
#else
cout<</*(unsigned int)*/theColor.ToInt()<<endl;
cout<<theColor.ToWinRGBInt()<<endl;
//Color ret=Color::WinRGBToColor(16711680);
Color c=Color::WinRGBToColor(16761798);
cout<<c<<endl;
#endif
cout<<"RGB:"<<(int)Color::GetRedValue(16761798)<<","<<(int)Color::GetGreenValue(16761798)<<","<<(int)Color::GetBlueValue(16761798)<<endl;
}
int main()
{
Test7();
system("pause");
return 0;
}
//VS2012编译
//计算雅可比符号(d/n)
#include <functional>
#include <iostream>
using namespace std;
int neg_one(int m);
int two(int m);
int Jacobi(int d,int n);
int Jacobi1(int d,int n);
function<int(int)> f1=neg_one;
function<int(int)> f2=two;
// function存放普通函数
#if 1
function<int(int,int)> JacobiSymbol=Jacobi;
#else
function<int(int,int)> JacobiSymbol=Jacobi1;//有问题
#endif
int neg_one(int m)
{
if( m%4 == 1 )
return 1;
if( m%4 == 3 )
return -1;
}
int two(int m)
{
if( m%8 == 1 || m%8 == 7 )
return 1;
if( m%8 == 3 || m%8 == 5 )
return -1;
}
int Jacobi1(int m,int n)
{
if(n%m==0)
return 0;
int q, s, t, d, mul=1;
s=m;
t=n;
loon:
if( m>n )
{
m%=n;
}
while( m%2 == 0 )
{
m/=2;
#if 1
mul*=f2(n);
#else
mul*=two(n);
#endif
}
if( m == -1 )
{
#if 0
auto fun0=[=](int m)->int{
if( m%4 == 1 )
return 1;
if( m%4 == 3 )
return -1;
};
mul*=fun0(n);
#else
//mul*=neg_one(n);
mul*=f1(n);
#endif
goto mark;
}
if( m == 1 )
{
goto mark;
}
q=n;
n=m;
m=q;
if( (n-1)*(m-1)%8 != 0 )
{
mul*=-1;
}
goto loon;
mark:
return mul;
}
/*
计算雅可比符号(d/n),n>2且为奇整数
Jacobi符号的值:
0表示d可以整除n
1表示d是模n的平方剩余(?NOSURE)
-1表示d是模n的非平方剩余(?NOSURE)
*/
int Jacobi(int d,int n)
{
int x=d;
int y=n;
int j=1;
int t;
while(y>1){
x=x%y;
if(x>y/2){
x=y-x;
if(y%4==3) j=-1*j;
}
if(x==0) {x=1;y=0;j=0;}
while(x%4==0){
x=x/4;
}
if(x%2==0){
x=x/2;
if((y%8==3)||(y%8==5)) j=-1*j;
}
if((x%4==3)&&(y%4==3)){
j=-1*j;
t=x;
x=y;
y=t;
}
else{
t=x;
x=y;
y=t;
}
}
return j;
}
void Test6()
{
int n=45;
for(int x=1;x<180;x++)
{
//cout<<JacobiSymbol(x,n)<< endl;
cout<<"Jacobi(x="<<x<<"/n="<<n<<")="<<JacobiSymbol(x,n)<<endl;
}
}
int main()
{
Test6();
system("pause");
return 0;
}
http://www.cnblogs.com/huoyao/p/4248925.html
白板放在代替金牌的位置
#include <algorithm>
// 带金牌a,替金b的麻将牌排序
bool MJSortFunc(BYTE i,BYTE j,BYTE a,BYTE b)
{
//a放在最左边
#if 1
if(i==a && j==a)
return false;
if(i==a && j!=a)
return true;
#else
if(i==a)
return true;
#endif
if(j==a)
return false;
if(i==b)
i=a;
if(j==b)
j=a;
return (i<j);//升序
}
//排序,根据牌值排序
bool CGameLogic::SortCardList( BYTE cbCardData[MAX_COUNT], BYTE cbCardCount )
{
//数目过虑
if (cbCardCount==0||cbCardCount>MAX_COUNT) return false;
BYTE MagicData = SwitchToCardData(GetMagicIndex());
std::sort(cbCardData,cbCardData+cbCardCount,std::bind(MJSortFunc,std::placeholders::_1,std::placeholders::_2,MagicData,0x37));
return true;
}
http://www.cnblogs.com/haippy/p/3237213.html
https://my.oschina.net/shou1156226/blog/802859
深入应用C++ 11:代码优化与工程级应用
祁宇 著
2015.5出版
技术博客http://www.cnblogs.com/qicosmos/
本书示例代码需要支持C++ 11的编译器:
Windows:Visual Studio 2013。
Linux:GCC 4.8+或者Clang 3.4。
由于少数代码用到了boost库,还需要编译boost 1.53或更新的boost库。
chap1 使用C++ 11让程序更简洁、更现代
1.1类型推导
C++ 11引入了auto和decltype关键字实现类型推导。
1.1.1 auto类型推导
auto并不能代表一个实际的类型声明,只是一个类型声明的占位符。
使用auto声明的变量必须马上初始化,以让编译器推断出它的实际类型,并在编译时将auto占位符替换为真正的类型。
非static的局部变量默认就是具有自动存储期的。
3.auto的限制
auto是不能用于函数参数的。
4.什么时候用auto
auto简化STL迭代器(iterator)变量的定义
注意:auto是一个很强大的工具,但不加选择地随意使用auto,会带来代码可读性和可维护性的严重下降。因此,在使用auto的时候,一定要权衡好它带来的价值和相应的损失。
1.1.2 decltype关键字
若仅希望得到类型,而不需要(或不能)定义变量的时候应该怎么办呢?
C++ 11新增了decltype关键字,用来在编译时推导出一个表达式的类型。
1.1.3 返回类型后置语法——auto和decltype的综合使用
20170331添加:
5.7右值引用
右值引用的目的是为了实现“移动语义”和“完美转发”。
将普通的引用定义为Type&,那么右值引用的写法则是Type&&,通过std::move函数,可以将左值转换为右值引用,move可理解为static_cast<T&&><obj>。
C++ 11有一个定义:“基于安全的原因,具名参数将不被认定为右值,即便是右值引用,必须使用move来获取右值”。
5.7.2移动语义
移动是为了消除不必要的对象复制,为提高效率而存在的。
VS的DEBUG模式默认没有开启RVO。
在C++ 11之前,使用const A&也可以将函数内的变量取出,但由于是const引用,所以并不能对变量进行操作,而非const的右值引用则没有该限制。
3种构造方法:
默认复制构造(浅拷贝)、复制构造(深拷贝)、移动构造
5.7.3完美转发
完美转发是为了能更简洁明确地定义泛型函数——将一组参数原封不动地传给另一个函数。原封不动指的是参数数值和类型不变,参数的const属性不变。
C++ 11定义的T&&推导规则是,右值实参为右值引用,左值实参为左值引用,参数属性不变。
5.8显示虚函数重写
override和final并不是关键字,只有在特定的位置才有特殊含义,在其他地方仍可当变量来使用。为了保存向后兼容,override是选择性的。
20170409添加:
// 20170409.cpp : 定义控制台应用程序的入口点。
//
#include "stdafx.h"
// VS2012编译
#include <set>
#include <iostream>
template <typename ObType, typename BinaryFunction>
bool isGroup12(const std::set<ObType> & S, BinaryFunction & op)
{
/*
isGroup returns true or false depending on whether the set S
along with the operator op is a group in the Algebraic sense.
That is, S is a group if and only if all the 4 following
conditions are true:
(1) If a, b in S, then a op b in S
(2) If a, b, c in S, then (a + b) + c = a + (b + c)
(3) There is an element 0 in S such that a + 0 = 0 + a for all a in S
(4) If a in S, then there is a b in S such that a + b = b + a = 0
*/
typename std::set<ObType>::const_iterator beg(S.cbegin()), offend(S.cend());
bool noProblems = true;
for (std::set<ObType>::const_iterator ia = beg; ia != offend && noProblems; ++ia)
{
for (std::set<ObType>::const_iterator ib = beg; ib != offend && noProblems; ++ib)
{
// ---------- (1) --------------
if (S.count(op(*ia, *ib)) == 0)
noProblems = false;
// -----------------------------
for (std::set<ObType>::const_iterator ic = beg; ic != offend && noProblems; ++ic)
{
// ---------- (2) -------------
//is wrong
//if (((*ia + *ib) + *ic) != (*ia + (*ib + *ic)))
// noProblems = false;
if ( op( op(*ia,*ib), *ic) != op( *ia, op( *ib, *ic)))
noProblems = false;
// ----------------------------
}
}
}
return noProblems;
}
template <typename ObType, typename BinaryFunction>
bool isGroup3( const std::set<ObType> & S, BinaryFunction & op)
{
// ... important define BinaryFunction as taking const args !
typename std::set<ObType>::const_iterator beg(S.cbegin()), offend(S.cend());
for (std::set<ObType>::const_iterator ia = beg; ia != offend; ++ia)
{
// ---------- (3) -------------
/* let e be an *ia */
ObType e = *ia;
bool isGroup = true;
for ( auto ia2 : S) {
if( op(ia2, e) != ia2 || op( e, ia2) != ia2) {
isGroup = false;
break;
}
// identity found, set e_ in class to e and return
if( isGroup) {
// e_ = e;
return true;
}
}
}
/* identity not found, this is not a group */
return false;
}
template <typename T>
class Plus
{
public:
T operator() (const T & x, const T & y) { return x + y; };
};
int main()
{
#if 1
int a1[]={0, 1, -1};
int n1=sizeof(a1)/sizeof(int);
std::set<int> S1(a1,a1+n1);
int a2[]={0};
int n2=sizeof(a2)/sizeof(int);
std::set<int> S2(a2,a2+n2);
#else
std::set<int> S1 = { 0, 1, -1 };//这种写法在VS2013以后支持
std::set<int> S2 = { 0 };//这种写法在VS2013以后支持
#endif
class Plus<int> p;
std::cout << isGroup12(S1, p)<<std::endl;
std::cout << isGroup3(S1, p)<<std::endl;
system("pause");
return 0;
}
20170413添加:
使用STL通用算法find_if()在list中搜索对象
这是find()的一个更强大的版本。这个例子演示了find_if(),它接收一个函数对象的参数作为参数,并使用它来做更复杂的评价对象是否和给出的查找条件相符。
// VS2012编译
#include <iostream>
#include <string>
#include <list>
#include <vector>
#include <algorithm>
#include <functional>//greater
using namespace std;
// 类比较,重载了()操作符
class personIsIn1492
{
public:
bool operator()(string& personRecord)
{
return personRecord.substr(0,4)=="1492";//第二个参数是要截的长度,不是截取结束的位置
}
};
void Test1()
{
list<string> persons;
persons.push_back("1487迪亚士");
persons.push_back("1492.10.12哥伦布 国庆日");
persons.push_back("1519麦哲伦");
persons.push_back("1649.1查理二世");
persons.push_back("1774中原王伦起义");
#if 1
/*
捕获列表捕获的是调用该表达式函数内的局部非静态变量,对于那些函数内的静态变量和定义在函数外的变量,Lambda表达式可以直接使用。
下面Lambda表达式中捕获了变量str,返回类型是bool。
编译器在解释Lambda表达式时,会解释成一个未命名类的未命名对象,该类包含了一个重载函数调用操作符的函数,如果捕获列表中包含有值捕获参数时,那么该类中会有一个相对应的成员参数
*/
string str="1492";
list<string>::iterator personIterator = find_if (persons.begin(), persons.end(),[str](string& personRecord)->bool{
if(personRecord.substr(0,4)==str)return true;
return false;
});
#else
// 使用重载了()操作符类对象比较
list<string>::iterator personIterator = find_if (persons.begin(), persons.end(),personIsIn1492());
#endif
if (personIterator==persons.end()) {
cout << "person not found in list" << endl;
}
else {
cout << *personIterator << endl;
}
}
class Grade
{
public:
Grade(int id,string name,int score)
{
ID=id;
Name=name;
Score=score;
}
int ID;
string Name;
int Score;
};
//针对Grade的vector对象进行排序
//定义函数对象用来排序
class sort_Grade
{
//函数对象的最大好处是可以内联,效率极高
public:
sort_Grade(){}
bool operator()(Grade X,Grade Y)const
{
//return X.Score<Y.Score;//按成绩的升序排
return X.Score>Y.Score;//按成绩的降序排
}
};
void Test2()
{
vector<Grade> finalGrade;
finalGrade.push_back(Grade(1,"A",56));
finalGrade.push_back(Grade(2,"B",57));
finalGrade.push_back(Grade(3,"C",58));
//当定义了用于排序的函数对象后就可以直接调用sort算法进行排序了
#if 1
//sort中使用Lambda表达式:
sort(finalGrade.begin(),finalGrade.end(),[](Grade X,Grade Y)->bool{
//return X.Score<Y.Score;//按成绩的升序排
return X.Score>Y.Score;//按成绩的降序排
});
#else
//排序,根据函数对象,函数对象的最大好处是可以内联,效率极高
sort(finalGrade.begin(),finalGrade.end(),sort_Grade());
#endif
int a=0;
}
void Test3()
{
int a[10]={0};
int N=5;
vector<int> b;
for(int i=0;i<N;i++)
{
cin>>a[i];
b.push_back(a[i]);
}
#if 1
//sort中使用Lambda表达式:
sort(a,a+N,[](int i,int j)->bool{
return (i>j);//降序排
});
sort(b.begin(),b.end(),[](int i,int j)->bool{
return (i<j);//升序排
});
#else
sort(a,a+N,greater<int>());//降序排列
sort(b.begin(),b.end());//升序排列
#endif
for(int i=0;i<N;i++)
cout<<a[i]<<" ";
cout<<endl;
for(int i=0;i<N;i++)
cout<<b[i]<<" ";
}
// 函数比较,例如带金牌的麻将牌排序
bool func(int i,int j,bool less,int a)
{
//a放在最左边
if(i==a)
return true;
if(j==a)
return false;
return less?(i<j):(i>j);//升序:降序
}
void Test4()
{
vector<int>::iterator Iter;
vector<int> the_vector;
int temp;
for( int i = 0; i < 5; i++ )
{
cin>>temp;
the_vector.push_back(temp);//vector无push_front方法
}
#if 1
// bind函数,用于函数绑定的模版,它可以指定函数中的部分参数,也可以是全部参数
sort(the_vector.begin(),the_vector.end(),bind(func,placeholders::_1,placeholders::_2,true,4));//升序排列,4放在最左边
//sort(the_vector.begin(),the_vector.end(),bind(func,placeholders::_1,placeholders::_2,false,4));//降序排列,4放在最左边
#else
sort(the_vector.begin(),the_vector.end(),less<int>());//升序排列
//sort(the_vector.begin(),the_vector.end(),greater<int>());//降序排列
#endif
cout<<"the_vector=";
for(Iter=the_vector.begin();Iter!=the_vector.end();Iter++)
cout<< " "<<*Iter;
cout<<endl;
}
void Test5()
{
//string str="abcdadcdefdde!@234";
string str="ABCDADCDEFDDE!@234";
#if 0
transform(str.begin(),str.end(),str.begin(),[](char ch)->char{return ch+1;});
#else
// 将字符串变成大写
//transform(str.begin(),str.end(),str.begin(),toupper);
// 将所有的字符变成小写
transform(str.begin(),str.end(),str.begin(),tolower);
#endif
cout<<str;
}
int main(int argc, char* argv[])
{
Test1();
Test2();
//Test3();
Test4();
Test5();
system("pause");
return 0;
}
20170417添加:
//VS2012编译
#include<cstdlib>
#include<functional>
#include<iostream>
#include<string>
using namespace std;
//ToInt成员函数的返回值与WinGDI.h的RGB宏或VB6的RGB函数值是不一致的,请不要混淆
//typedef unsigned long D3DCOLOR;
class Color
{
public:
int mRed;
int mGreen;
int mBlue;
int mAlpha;//255表示完全不透明
static Color Black;
static Color White;
static Color Empty;
public:
//缺省构造函数
Color():mRed(0),mGreen(0),mBlue(0),mAlpha(255){}
Color(int theRed,int theGreen,int theBlue,int theAlpha=0xFF):mRed(theRed),mGreen(theGreen),mBlue(theBlue),mAlpha(theAlpha){}
//拷贝构造函数
Color(const Color& c):mRed(c.mRed),mGreen(c.mGreen),mBlue(c.mBlue),mAlpha(c.mAlpha){}
//操作符重载
int& operator[](int theIdx);
int operator[](int theIdx)const;
Color& operator=(const Color& c){mRed=c.mRed;mGreen=c.mGreen;mBlue=c.mBlue;mAlpha=c.mAlpha;return *this;}
//inline函数
int GetRed()const{return mRed;}
int GetGreen()const{return mGreen;}
int GetBlue()const{return mBlue;}
int GetAlpha()const{return mAlpha;}
unsigned long ToInt()const{return (mAlpha<<24)|(mRed<<16)|(mGreen<<8)|(mBlue);}//返回值与D3DCOLOR_ARGB宏是一致的
unsigned long ToWinRGBInt()const{return (0<<24)|(mBlue<<16)|(mGreen<<8)|(mRed);}
static Color& WinRGBToColor(unsigned long lng);
static unsigned char GetRedValue(unsigned long lng);
static unsigned char GetGreenValue(unsigned long lng);
static unsigned char GetBlueValue(unsigned long lng);
friend ostream& operator<<(ostream& os,const Color& c);//put-to操作符<<
};
Color& Color::WinRGBToColor(unsigned long lng)
{
unsigned char b[10]={0};
//unsigned char b[4]={0};
memcpy(&b[0],&lng,4);
return Color(b[0],b[1],b[2],b[3]);
//int i[4]={0};
//i[0]=b[0];
//i[1]=b[1];
//i[2]=b[2];
//i[3]=b[3];
//return Color(i[0],i[1],i[2],i[3]);
//return Color((int)b[0],(int)b[1],(int)b[2],(int)b[3]);
}
unsigned char Color::GetRedValue(unsigned long lng)
{
return (unsigned char)(lng);
}
unsigned char Color::GetGreenValue(unsigned long lng)
{
return (unsigned char)(unsigned short((lng)>>8));
}
unsigned char Color::GetBlueValue(unsigned long lng)
{
return (unsigned char)((lng)>>16);
}
ostream& operator<<(ostream& os,const Color& c)
{
os<<"ARGB:"<<c.mAlpha<<","<<c.mRed<<","<<c.mGreen<<","<<c.mBlue;
return os;
}
int& Color::operator[](int theIdx)
{
static int aJunk=0;
switch(theIdx)
{
case 0:return mRed;
case 1:return mGreen;
case 2:return mBlue;
case 3:return mAlpha;
default:return aJunk;
}
}
int Color::operator[](int theIdx)const
{
switch(theIdx)
{
case 0:return mRed;
case 1:return mGreen;
case 2:return mBlue;
case 3:return mAlpha;
default:return 0;
}
}
//ARGB:255,255,0,0
//4294901760
//ARGB:0,255,0,0
//16711680
//ARGB:0,0,0,255
//255
//ARGB:255,0,0,255
//4278190335
//16711680
void Test7()
{
//const Color &theColor=Color(255,0,0);
//const Color &theColor=Color(255,0,0,255);
//const Color &theColor=Color(255,0,0,0);
//const Color &theColor=Color(0,0,255,0);//blue
const Color &theColor=Color(0,0,255,255);//blue
cout<<theColor<<endl;
#if 1
// function存放类的公有成员函数,使用bind绑定成员函数和对象指针,使用placeholders::_1~placeholders::_20占位符来表示函数的参数数量
function<unsigned long()> mf1=bind(&Color::ToInt,theColor);
function<unsigned long()> mf2=bind(&Color::ToWinRGBInt,theColor);
cout<<mf1()<<endl;
cout<<mf2()<<endl;
// function存放静态函数
function<Color(unsigned long)> smf1=Color::WinRGBToColor;
Color c=smf1(16761798);
cout<<c<<endl;
#else
cout<</*(unsigned int)*/theColor.ToInt()<<endl;
cout<<theColor.ToWinRGBInt()<<endl;
//Color ret=Color::WinRGBToColor(16711680);
Color c=Color::WinRGBToColor(16761798);
cout<<c<<endl;
#endif
cout<<"RGB:"<<(int)Color::GetRedValue(16761798)<<","<<(int)Color::GetGreenValue(16761798)<<","<<(int)Color::GetBlueValue(16761798)<<endl;
}
int main()
{
Test7();
system("pause");
return 0;
}
//VS2012编译
//计算雅可比符号(d/n)
#include <functional>
#include <iostream>
using namespace std;
int neg_one(int m);
int two(int m);
int Jacobi(int d,int n);
int Jacobi1(int d,int n);
function<int(int)> f1=neg_one;
function<int(int)> f2=two;
// function存放普通函数
#if 1
function<int(int,int)> JacobiSymbol=Jacobi;
#else
function<int(int,int)> JacobiSymbol=Jacobi1;//有问题
#endif
int neg_one(int m)
{
if( m%4 == 1 )
return 1;
if( m%4 == 3 )
return -1;
}
int two(int m)
{
if( m%8 == 1 || m%8 == 7 )
return 1;
if( m%8 == 3 || m%8 == 5 )
return -1;
}
int Jacobi1(int m,int n)
{
if(n%m==0)
return 0;
int q, s, t, d, mul=1;
s=m;
t=n;
loon:
if( m>n )
{
m%=n;
}
while( m%2 == 0 )
{
m/=2;
#if 1
mul*=f2(n);
#else
mul*=two(n);
#endif
}
if( m == -1 )
{
#if 0
auto fun0=[=](int m)->int{
if( m%4 == 1 )
return 1;
if( m%4 == 3 )
return -1;
};
mul*=fun0(n);
#else
//mul*=neg_one(n);
mul*=f1(n);
#endif
goto mark;
}
if( m == 1 )
{
goto mark;
}
q=n;
n=m;
m=q;
if( (n-1)*(m-1)%8 != 0 )
{
mul*=-1;
}
goto loon;
mark:
return mul;
}
/*
计算雅可比符号(d/n),n>2且为奇整数
Jacobi符号的值:
0表示d可以整除n
1表示d是模n的平方剩余(?NOSURE)
-1表示d是模n的非平方剩余(?NOSURE)
*/
int Jacobi(int d,int n)
{
int x=d;
int y=n;
int j=1;
int t;
while(y>1){
x=x%y;
if(x>y/2){
x=y-x;
if(y%4==3) j=-1*j;
}
if(x==0) {x=1;y=0;j=0;}
while(x%4==0){
x=x/4;
}
if(x%2==0){
x=x/2;
if((y%8==3)||(y%8==5)) j=-1*j;
}
if((x%4==3)&&(y%4==3)){
j=-1*j;
t=x;
x=y;
y=t;
}
else{
t=x;
x=y;
y=t;
}
}
return j;
}
void Test6()
{
int n=45;
for(int x=1;x<180;x++)
{
//cout<<JacobiSymbol(x,n)<< endl;
cout<<"Jacobi(x="<<x<<"/n="<<n<<")="<<JacobiSymbol(x,n)<<endl;
}
}
int main()
{
Test6();
system("pause");
return 0;
}
http://www.cnblogs.com/huoyao/p/4248925.html
白板放在代替金牌的位置
#include <algorithm>
// 带金牌a,替金b的麻将牌排序
bool MJSortFunc(BYTE i,BYTE j,BYTE a,BYTE b)
{
//a放在最左边
#if 1
if(i==a && j==a)
return false;
if(i==a && j!=a)
return true;
#else
if(i==a)
return true;
#endif
if(j==a)
return false;
if(i==b)
i=a;
if(j==b)
j=a;
return (i<j);//升序
}
//排序,根据牌值排序
bool CGameLogic::SortCardList( BYTE cbCardData[MAX_COUNT], BYTE cbCardCount )
{
//数目过虑
if (cbCardCount==0||cbCardCount>MAX_COUNT) return false;
BYTE MagicData = SwitchToCardData(GetMagicIndex());
std::sort(cbCardData,cbCardData+cbCardCount,std::bind(MJSortFunc,std::placeholders::_1,std::placeholders::_2,MagicData,0x37));
return true;
}
相关文章推荐
- Effective C++ 学习笔记(11)
- 【菜鸟C++学习笔记】11.内联函数与const成员函数
- c++ 11学习笔记--右值引用和移动构造语义
- MySQL学习笔记_11_Linux下C++/C连接MySQL数据库(一)
- Effective C++ 学习笔记11
- C++学习笔记(11)——虚函数的特性
- 【C++研发面试笔记】11. 基本数据结构-红黑树RBT
- C++ 11 学习笔记(不断更新)
- c++ 11学习笔记-- 常量表达式(constexpr)
- 学习笔记-多项式的加减乘数及微分的C++实现15/11/02
- C++ FAQ学习笔记 11 章 析构函数
- C++ 11 笔记 (三) : auto
- C++ 11 笔记 (二) : for循环
- c++ 11学习笔记--智能指针
- 【C++学习笔记】11_多维数组
- c/c++学习笔记(11)
- C++ 11 笔记 (一) : lambda
- C++ 11 笔记 (五) : std::thread
- C++学习笔记11-面向对象2
- 谭浩强C++笔记(11-12章)