zoukankan      html  css  js  c++  java
  • [C++] 11 新特性

    参考链接:http://blog.csdn.net/huang_xw/article/details/8764346 

    http://blog.jobbole.com/44015/ 

    http://blog.csdn.net/kturing/article/details/45286823

    auto:自动类型推断和返回值占位,与c++98定义不同(临时变量定义)

    //  auto a;                 // 错误,没有初始化表达式,无法推断出a的类型  
    //  auto int a = 10;        // 错误,auto临时变量的语义在C++11中已不存在, 这是旧标准的用法。  
      
    // 自动帮助推导类型  
        auto a = 10;  
    
    //我们可以使用valatile,pointer(*),reference(&),rvalue reference(&&) 来修饰auto
    auto k = 5; 
    auto* pK = new auto(k);
    
    //函数和模板参数不能被声明为auto
    
    //不能用于类型转换或其他一些操作,如sizeof和typeid
    int value = 123;  
    auto x2 = (auto)value; // no casting using auto 
    
    //定义在一个auto序列的变量必须始终推导成同一类型
    auto x1 = 5, x2='a'; //wrong
    
    //auto不能自动推导成CV-qualifiers(constant & volatile qualifiers),除非被声明为引用类型
    const int i = 99;  
    auto j = i;       // j is int, rather than const int  
    j = 100           // Fine. As j is not constant  
    auto& k = i;      // Now k is const int&  
    k = 100;          // Error. k is constant
    
    //auto会退化成指向数组的指针,除非被声明为引用
    int a[2]={0,1};
    auto ar = a;
    count<<typeid(ar).name()<<endl; // int
    
    auto &ar = a;
    count<<typeid(ar).name()<<endl; // int [2]

    nullptr: 替代NULL的宏定义,VS2010之前的版本,不支持此关键字。

    //0(NULL)和nullptr可以交换使用,但是nullptr是一个为空的指针,并不是一个整形,不能替代0
    int* p1 = 0;  
    int* p2 = nullptr;  
     
    if(p1 == p2) {}  
    if(p2) {}
    
    //不能将nullptr赋值给整形
    int n2 = nullptr;       // error 
    if(0 == nullptr) {}    // error  
    if(nullptr) {}    // error  
    
    //重载时,使用nullptr时 对应的是参数为指针的函数
    void foo(int)   {cout << "int" << endl;}  
    void foo(char*) {cout << "pointer" << endl;}  
      
    foo(0);       // calls foo(int)  
    foo(nullptr); // calls foo(char*) 
    

    decltype

    decltype(E)是一个标识符或者表达式的推断数据类型(“declared type”),它可以用在变量声明中作为变量的数据类型

    override: 表示函数应当重写基类中的虚函数。

    class B 
    {
    public:
       virtual void f(short) {std::cout << "B::f" << std::endl;}
    };
     
    class D : public B
    {
    public:
       virtual void f(int) override {std::cout << "D::f" << std::endl;}
    };
    //error:'D::f' : method with override specifier 'override' did not override any base class methods

    final: 表示派生类不应当重写这个虚函数。

    class B 
    {
    public:
       virtual void f(int) {std::cout << "B::f" << std::endl;}
    };
     
    class D : public B
    {
    public:
       virtual void f(int) override final {std::cout << "D::f" << std::endl;}
    };
     
    class F : public D
    {
    public:
       virtual void f(int) override {std::cout << "F::f" << std::endl;}
    };
    //被标记成final的函数将不能再被F::f重写

    Strongly-typed enums

    enum class Options {None, One, All}; //强类型枚举由关键字enum class标识,它不会将枚举常量暴露到外层作用域中,也不会隐式转换为整形
    Options o = Options::All;

    Smart Pointers 智能指针

    unique_ptr: 如果内存资源的所有权不需要共享,就应当使用这个(它没有拷贝构造函数),但是它可以转让给另一个unique_ptr(存在move构造函数)。有点像auto_ptr
    std::unique_ptr<int> p1(new int(42));
    std::unique_ptr<int> p2 = std::move(p1); // transfer ownership
    
    shared_ptr: 如果内存资源需要共享,那么使用这个
    weak_ptr:持有被shared_ptr所管理对象的引用,但是不会改变引用计数值。它被用来打破依赖循环
    auto_ptr: 已废弃

    Lambda

    [captures] (params) -> ret {Statments;}  
    
    #include <iostream>  
      
    using namespace std;  
      
    int main()  
    {  
        auto func = [] () { cout << "Hello world"; };  
        func(); // now call the function  
    } 
    /*
    [] 不截取任何变量
    [&} 截取外部作用域中所有变量,并作为引用在函数体中使用
    [=] 截取外部作用域中所有变量,并拷贝一份在函数体中使用
    [=, &foo]   截取外部作用域中所有变量,并拷贝一份在函数体中使用,但是对foo变量使用引用
    [bar]   截取bar变量并且拷贝一份在函数体重使用,同时不截取其他变量
    [this]            截取当前类中的this指针。如果已经使用了&或者=就默认添加此选项。
    */
    string name;  
    cin>> name;  
    return global_address_book.findMatchingAddresses(   
        // notice that the lambda function uses the the variable 'name'  
        [&] (const string& addr) { return name.find( addr ) != string::npos; }   
    ); 

    参考链接:http://blog.csdn.net/srzhz/article/details/7934652

    控制默认函数——默认或者禁用

    class X {
            //
    
            X& operator=(const X&) = delete;   // 禁用类的赋值操作符
            X(const X&) = delete;
        };
    
    //但是其实可以用privae啊!

    std::bind

    //bind()接受一个函数(或者函数对象,或者任何你可以通过”(…)”符号调用的事物),生成一个其有某一个或多个函数参数被“绑定”或重新组织的函数对象
    int f(int, char, double);
    // 绑定f()函数调用的第二个和第三个参数,
    // 返回一个新的函数对象为ff,它只带有一个int类型的参数
    auto ff = bind(f, _1, ‘c’, 1.2);
    int x = ff(7);                //  f(7, ‘c’, 1.2);
    //“_1″是一个占位符对象,用于表示当函数f通过函数ff进行调用时,函数ff的第一个参数在函数f的参数列表中的位置
    
    //bind()也可以被看做是bind1st()和bind2nd()的替代品

    std::function

    template< class R, class... Args >
    class function<R(Args...)>

    struct X {
                    int foo(int);
            };
    
            // 所谓的额外参数,
            // 就是成员函数默认的第一个参数,
            // 也就是指向调用成员函数的对象的this指针
            function<int (X*, int)> f;
            f = &X::foo;            // 指向成员函数
    
            X x;
            int v = f(&x, 5);  // 在对象x上用参数5调用X::foo()
            function<int (int)> ff = std::bind(f, &x, _1);    // f的第一个参数是&x
            v = ff(5);                // 调用x.foo(5)
    
    //可以看做是C++98标准库中函数对象mem_fun_t, pointer_to_unary_function等的替代品

     初始化

    int arr[3]{1, 2, 3};  
    vector<int> iv{1, 2, 3};  
    map<int, string>{{1, "a"}, {2, "b"}};  
    string str{"Hello World"};

    for循环

    map<string, int> m{{"a", 1}, {"b", 2}, {"c", 3}};  
    for (auto p : m){  
        cout<<p.first<<" : "<<p.second<<endl;  
    } 
    int my_array[5] = {1, 2, 3, 4, 5};
    // double the value of each element in my_array:
    for (int &x : my_array) {
        x *= 2;
    }
    

    std::tuple

    类似std::pair

    //init
    template <class ...Types> class tuple;
    typedef std::tuple <int, double, long &, const char *> test_tuple;
    long lengthy = 12;
    test_tuple proof (18, 6.5, lengthy, "Ciao!");
    
    auto record = std::make_tuple("Hari Ram", "New Delhi", 3.5, 'A');
     
    //ge/set eles
    lengthy = std::get<0>(proof);  // Assign to 'lengthy' the value 18.
    int len = proof.get<1>(); //获取第二个值
    std::get<3>(proof) = " Beautiful!";  // Modify the tuple’s fourth element.
    
    //two tuples have the same elements type
    typedef std::tuple <int , double, string       > tuple_1 t1;
    typedef std::tuple <char, short , const char * > tuple_2 t2 ('X', 2, "Hola!");
    t1 = t2; // Ok, first two elements can be converted,
    
    std::string name ; float gpa ; char grade ;
    std::tie(name, std::ignore, gpa, grade) = record ; // std::ignore helps drop the place name
    std::cout << name << ' ' << gpa << ' ' << grade << std::endl ;
    
    std::tie(std::ignore,std::ignore,y) = tp; //std::ignore占位符来表示不解某个位置的值,只解第三个值了
    
    //size type 
    std::tuple_size<T>::value returns the number of elements in the tuple T,
    std::tuple_element<I, T>::type returns the type of the object number I of the tuple T.
    std::tuple_element<1,Tuple>::type second = std::get<1> 
    (mytuple);
    
    //tuple_cat连接多个tupe
    int main()
    {
    std::tuple<int, std::string, float> t1(10, "Test", 
    3.14);
    int n = 7;
    auto t2 = std::tuple_cat(t1, std::make_pair("Foo", 
    "bar"), t1, std::tie(n)); //the variable ele  is reference
    n = 10;
    print(t2);
    }
    //输出结果:
    
    (10, Test, 3.14, Foo, bar, 10, Test, 3.14, 10
    

    右尖括号

     int my_array[5] = {1, 2, 3, 4, 5};
    // double the value of each element in my_array:
    for (int &x : my_array) {
        x *= 2;
    }

    explicit

    In C++11, the explicit keyword can now be applied to conversion operators. As with constructors, it prevents the use of those conversion functions in implicit conversions. However, language contexts that specifically require a boolean value (the conditions of if-statements and loops, as well as operands to the logical operators) count as explicit conversions and can thus use a bool conversion operator

    long long int

    c++03中long int至少和int类型位数一样,在某些编译器中是64位,有的是32,在C++11中引入long long int,至少与long int位数一样,不少于64位。

    static_assert(express, error_msg)

    静态断言,在编译期间测试,大多测试编译器环境,例如判断long int类型的位数是否为64

    sizeof

    c++03可以用在基本类型和对象中,但是不可以用在对象成员中

    struct MyType{MemberType member};
    sizeof(MyType::member);//ok
    

    正则表达式

    std::regex 
    std::match_results
    std::regex_search

    散列表

    std::unorderd_set
    std::unorderd_multiset
    std::unorderd_map
    std::unorderd_multimap

    constexpr

    允许将变量声明为constexpr类型让编译器来验证变量的值是否是一个常量表达式。 
    声明为constexpr的变量一定是一个常量,而且必须用常量表达式初始化: 

    1. 是一种很强的约束,更好的保证程序的正确定语义不被破坏;
    2. 编译器可以对constexper代码进行非常大的优化,例如:将用到的constexpr表达式直接替换成结果;
    3. 相比宏来说没有额外的开销。
    constexpr int mf = 0; // 0 是常量表达式 
    constexpr int limit = mf + 1; // mf + 1 是常量表达式 
    constexpr int sz = size(); // 只有当 size() 是一个constexpr函数时才是一条正确的声明语句

    随机数生成器

  • 相关阅读:
    MySQL高级查询总结
    MySQL数据库作业
    MySQLdump备份还原命令
    MySQL之Join
    MySQL课堂作业(一)
    Mysql数据库
    Js实例之简易计算器
    JS系统函数
    js课堂作业之转换月份
    C++ Name Mangling 为什么不编码返回值参数
  • 原文地址:https://www.cnblogs.com/zengyou/p/3709790.html
Copyright © 2011-2022 走看看