您的位置:首页 > 编程语言 > C语言/C++

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;

}


内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: