• C++ 11 snippets , 2


    <1>auto ,initializer_list<T>,auto指向函数指针的简易,和typdef 定义的类型执行函数指针有多复杂。

    #include <iostream>
    #include <initializer_list>
    #include <string>
    using namespace std;
    
    template <typename  T>
    T sum(initializer_list<T> rh)
    {
        T val;
        for(auto p= rh.begin();p!=rh.end();p++)
        {
            val+= *p;
        }
        return val;
    }
    
    
    
    int main()
    {
        // use init list
        cout << sum({1,2,3,4,5}) <<endl;
        cout << sum({1.0,2.0,3.1,4.0,5.0}) <<endl;
    
        //
        cout << "use auto to point the function sum" <<endl;
        auto dadd_func = sum<double>;
        auto iadd_func = sum<int>;
        auto tadd_func = sum<string>;
        cout << dadd_func({1,23,4,5}) <<endl;
        cout << iadd_func({1,1,3,4,5}) <<endl;
        cout << tadd_func({"houdini","maya","json"}) <<endl;
    
        cout << "
    use the typedef to pointer
    ";
        typedef int     (*td_int_sum)(initializer_list<int> rh);
        typedef string  (*td_str_sum)(initializer_list<string> rh);
        td_int_sum int_add = sum<int>;
        td_str_sum str_add = sum<string>;
        cout << int_add({1,2,3,4,5,6}) <<endl;
        cout << str_add({"s1","s2","s5"}) << endl;
    
        return 0;
    }
    View Code

    <2>funcional,std::generate,std::count_if

    #include <iostream>
    #include <math.h>
    #include <vector>
    #include <algorithm>
    #include <functional>
    
    using namespace std;
    
    double square(double x){return x*x;}
    
    int main()
    {
        vector <int> vars(10);
    
        generate(vars.begin(),vars.end(),std::rand);
        for_each(vars.begin(),vars.end(),[](int v){cout << v <<endl;});
    
        // lambda can transfer local variable
        int sum = 0;
        for_each(vars.begin(),vars.end(),[&sum](int v){sum+=v;});
        cout << "the sum is " << sum <<endl;
    
        // <100 num
        cout << "get <100 numbers" <<endl;
        cout << count_if(vars.begin(),vars.end(),[](int v){ return v<100;}) <<endl;
    
    
        // functional
        function<double(double)> ef1 = square;
        cout << ef1(2) <<endl;      // 4
    
        function<void(int var)> ef2 = [](int val){cout << val <<endl;};
        ef2(100);                   // 100
    
    
    
        return 0;
    }
    View Code

    <3> remove_if,vector,min_element,max_element

    include <iostream>
    #include <algorithm>
    #include <vector>
    #include <string>
    using namespace std;
    
    
    
    void cppRemove_if()
    {
        cout << "====cppRemove_if====
    ";
        int myInts[]{1,2,3,4,5,6,7,8};        // 1 2 3 4 5 6 7 8
        int *pbegin = myInts;
        int *pend = myInts + sizeof(myInts)/ sizeof(int);
        pend = remove_if(pbegin,pend,
                         [](const int &val)->bool{return val%2 == 1;});//2 4 5 8 ? ? ? ?
        for (int* p=pbegin; p!=pend; ++p)
            cout << ' ' << *p;
        cout << "
    ";
        cout << "====cppRemove_if====
    ";
    
    }
    
    int main()
    {
    
        vector<int> va{1,2,3,4,5,6};
    
        // find, if not find elements,will return last *iter;
        auto va_find2  = find(va.begin(),va.end(),2);
        auto va_find2e = find_if(va.begin(),va.end(),[](const int &x){return x==2;});
        cout << *va_find2 <<endl;
        cout << *va_find2e <<endl;
    
        cout << *min_element(va.begin(),va.end()) <<endl;
        cout << *max_element(va.begin(),va.end()) <<endl;
    
        auto min_max = minmax_element(va.begin(),va.end());
        cout << "min val:" <<*(min_max.first)<<endl;
        cout << "max val:" <<*(min_max.second)<<endl;
    
        cout << "remove the second elements 
    ";
        va.erase(va.begin()+1,va.begin()+2);
        for_each(va.begin(),va.end(),[](const int &x){cout << x <<endl;});
    
        
    
        cout << "remove by condition <5 
    ";
        va.erase(remove_if(va.begin(),va.end(),[](int x){return x <5;}),va.end());
        for_each(va.begin(),va.end(),[](const int &x){cout << x <<endl;});
    
    
        cppRemove_if();
        return 0;
    }
    View Code

     

     <4>binary_search,sort更加详细的用法:

    #include <iostream>
    #include <algorithm>
    #include <vector>
    #include <functional>
    using namespace std;
    
    
    template <typename T1>
    void ShowIntArray(const T1 begin, const T1 end)
    {
        for_each(begin,end,[](const int &x){cout << x <<" "; });
        cout << "
    ";
    }
    template <typename T>
    void ShowSTLArray(const T&cont)
    {
        auto iter = cont.begin();
        auto end = cont.end();
        for(;iter!=end;iter++)
        {
            cout << *iter <<" ";
        }
        cout <<endl;
    };
    
    
    void cpp_sort()
    {
        int a[]= {3,1,4,6,8,0};
        int *begin = a;
        int *end = a + 6;
    
    
        cout << "before sort:
    ";
        ShowIntArray(begin, end);
    
        sort(begin,end);
        cout << "after sort:
    ";
        ShowIntArray(begin, end);
    
        cout << "from large to small:
    ";
        sort(begin,end,[](const int &x,const int &y){return x>y;});
        ShowIntArray(begin, end);
    
        cout << "from small to large use less<int>():
    ";
        sort(begin,end,less<int>());
        ShowIntArray(begin, end);
    
        cout << "from large to small use greater<int>():
    ";
        sort(begin,end,greater<int>());
        ShowIntArray(begin, end);
    
    
        vector<string> vecStr{"Got","cool","features"};
        cout << "sort the sting array:
    ";
        ShowSTLArray(vecStr);
        auto strCmp = [](string &a,string &b)
        {
            return a.length() > b.length();
        };
        cout << "sort the array results:
    ";
        sort(vecStr.begin(),vecStr.end(),strCmp);
        ShowSTLArray(vecStr);
    
    }
    
    
    
    void cpp_binary_search()
    {
    
        cout << "=======search 01:==========
    ";
        std::vector<int> haystack {32132, 121, 3, 5, 9};
        std::vector<int> needles {1, 2, 3};
        sort(haystack.begin(),haystack.end());
        for (auto needle : needles)
        {
            cout << "Searching for " << needle << '
    ';
            if (binary_search(haystack.begin(), haystack.end(), needle))
            {
    
                cout << "Found " << needle << '
    ';
            }
            else
            {
                cout << "no dice!
    ";
            }
        }
        cout << "=======search 01:==========
    ";
    
    
        std::vector<int> haystack2 {32132, 121, 3, 5, 9,100,40,323};
        sort(haystack2.begin(),haystack2.end(),[](int &x,int &y){return x<y;});
        ShowSTLArray(haystack2);
    
        auto func =[](int i,int j)->bool{cout<< "i:" << i; cout << " j:"<<j;cout<<"
    ";return (i<j);};
        if (binary_search(haystack2.begin(),haystack2.end(),5,func))
        {
            cout << "found 5" <<endl;
        }
    
    
    }
    
    
    
    
    
    int main()
    {
        //cpp_sort();
        cpp_binary_search();
        return 0;
    }
    View Code

    binarySearch结果:

    Sort结果:

     

     <5> 线程大法

     (1) hello world thread:

    #include <iostream>
    #include <thread>
    #include <memory>
    using namespace std;
    
    
    void thread_task()
    {
        cout << "thread hello world
    ";
    }
    
    
    int main()
    {
        shared_ptr<thread> t(new thread(thread_task));
        t->join();
    
        return 0;
    }
    View Code

    (2)带参数的函数(bind方法,直接使用thread构造也可以)

    void thread_parm(const int &n,const string& name)
    {
        for(int i=0;i<n;i++)
        {
            cout << name <<":thread loop in " << i <<endl;
        }
    }
    
    void withParam()
    {
        thread t0(thread_parm,100,"houdini");
        thread t1(bind(thread_parm,100,"maya"));
        t0.join();
        t1.join();
    }
    
    int main()
    {
        withParam();
        return 0;
    }
    View Code

    (3)成员对象函数执行在线程中(也可以作用到智能指针对象)

    class HelloObject
    {
    public:
        void sayHello(const string& name,int n)
        {
            for(int i=0;i<n;i++)
            {
                cout << name << " thread: " << i <<endl;
            }
        }
    };
    
    void objectFunction()
    {
        HelloObject obj;
        thread t(&HelloObject::sayHello,&obj,"Json",6);
        t.join();
    
        // work with shared_ptr
        shared_ptr<HelloObject> objPtr(new HelloObject());
        thread tptr(&HelloObject::sayHello,objPtr,"Houdini",6);
        tptr.join();
    }
    
    int main()
    {
        objectFunction();
        return 0;
    }
    View Code

    (4)传递引用,头文件functional,std::ref()

    class FuncObj
    {
    public:
        void operator()()const
        {
            cout << this <<endl;
        }
    };
    void passRef()
    {
        auto obj = FuncObj();
        obj();
    
        //pass by value
        cout << "thread will pass by value
    ";
        thread t1(obj);
        t1.join();
    
        //pass by ref
        cout << "thread will pass by ref
    ";
        thread t2(ref(obj));
        t2.join();
    
    }
    
    
    int main()
    {
        passRef();
        return 0;
    }
    View Code

     结果:

    0x22fdff
    thread will pass by value
    0x7c6150
    thread will pass by ref
    0x22fdff

     普通的函数也可以

    void increment(int &value)
    {
        value++ ;
        cout << "value :" << value <<endl;
    
    }
    void passRef2()
    {
        int a = 10;
        thread t(increment,ref(a));
        t.join();
    }
    
    
    
    int main()
    {
        passRef2();
        return 0;
    }
    View Code

    (5)基本功能:

    匿名函数:get_id() 区分线程

    void lambdaTest()
    {
        vector <thread> threads;
        for(int i=0;i<5;i++)
        {
            threads.emplace_back(thread([](){cout << "thread id " << this_thread::get_id() << endl;}));
        }
    
        for(auto &t : threads)
        {
            t.join();
        }
    }
    
    
    
    
    
    int main()
    {
        lambdaTest();
        return 0;
    }
    View Code

     总线程数:

    cout << thread::hardware_concurrency() <<endl;

    (6)异常与线程

    标准处理方法

    struct Counter2
    {
        int value;
        Counter2():value(0){}
        void increment()
        {
            ++value;
        }
        void decrement()
        {
            if(value == 0)
            {
                throw string("value cannot be less than 0");
            }
    
            --value;
        }
    };
    
    
    struct Wrapper
    {
        Counter2 ct;
        mutex m;
    
        void increment()
        {
    
        }
        void decrement()
        {
            m.lock();
            try
            {
                ct.decrement();
            }
            catch (const string &e)
            {
                m.unlock();
                cout << e <<endl;
                throw e;
            }
    
            m.unlock();
        }
    };
    
    
    
    
    
    void exceptionLock()
    {
        Wrapper wap;
        wap.ct.value = 10;
    
        vector<thread> threads;
        for(int i=0;i<11;i++)
        {
            threads.emplace_back(thread([&wap](){
                wap.decrement();
    
            }));
        }
        for(auto &t:threads)
        {
            t.join();
        }
        cout << wap.ct.value << endl;
    }
    View Code

    (7)模仿Inter TBB parallel_for

    串行时间:87

    并行时间:19

    struct BlockRange
    {
        BlockRange():begin(0),end(0)
        {
    
        }
        int begin;
        int end;
    };
    
    class ApplyFoo
    {
    public:
        ApplyFoo(vector<int> *data):mData(data)
        {
        }
        void operator()(const BlockRange &range)const
        {
            for(int i=range.begin;i<range.end;i++)
            {
                (*mData)[i] += 5;
            }
        }
    private:
        vector<int> *mData;
    };
    
    
    template <typename T>
    void parallel_for(const T &body,int size,int begin)
    {
        auto nThreads = thread::hardware_concurrency();
        auto nValuesSize = size;
        auto perBlockSize =nValuesSize / nThreads;
        if(nValuesSize < nThreads)
        {
            BlockRange range;
            range.begin = begin;
            range.end = nValuesSize;
            body(range);
            return;
        }
        // building blocks
        vector<BlockRange> blocks;
        int index = begin;
        while(index <= nValuesSize)
        {
            BlockRange range;
            range.begin = index;
            range.end   = index+ perBlockSize;
            blocks.push_back(range);
            index += (perBlockSize) ;
        }
        // fix last block end size;
        blocks[blocks.size()-1].end = nValuesSize;
        // thread pool to run
        typedef shared_ptr<thread> thread_ptr;
        vector<thread_ptr> pools;
        for(BlockRange&r:blocks)
        {
            pools.emplace_back(new thread(body,r));
        }
        for(auto &t:pools)
        {
            t->join();
        }
    
    
    
    }
    
    
    void parallel()
    {
        vector<int> values(10000000);
        fill(values.begin(),values.end(),100);
    
        double start,end,cost;
        start=clock();
        parallel_for(ApplyFoo(&values),values.size(),10);
        end= clock();
        cost = end -start;
        cout << "parallel for cost time:" << cost <<endl;
    
    }
    void serial()
    {
        vector<int> values(10000000);
        fill(values.begin(),values.end(),100);
    
    
        double start,end,cost;
        start=clock();
        for(int i=0;i<values.size();i++)
        {
            values[i] += 5;
        }
        end= clock();
        cost = end -start;
        cout << "serial for cost time:" << cost <<endl;
    }
    
    int main()
    {
    
    
        parallel();
        serial();
        return 0;
    }
    View Code

    并行accumulation:

    10亿个元素相加:简直他妈的快飞起来了。

    串行时间:13063

    并行时间:1023

    #include <vector>
    #include <time.h>
    #include <iostream>
    #include <thread>
    #include <algorithm>
    using namespace std;
    
    struct BlockRange
    {
        BlockRange():begin(0),end(0),id(0)
        {
    
        }
        int begin;
        int end;
        int id;
    };
    
    class ApplyFoo
    {
    public:
        ApplyFoo(vector<int> *data):mData(data)
        {
        }
        void operator()(const BlockRange &range,vector<int> *des)const
        {
            auto value = int(0);
            for(int i=range.begin;i<range.end;i++)
            {
                value +=(*mData)[i];
            }
            (*des)[range.id] = value;
        }
    private:
        vector<int> *mData;
    
    };
    
    
    template <typename retType,typename T>
    retType parallel_add(const T &body,int size,int begin)
    {
        vector<retType> partial_accum;
        auto nThreads = thread::hardware_concurrency();
        auto nValuesSize = size;
        auto perBlockSize =nValuesSize / nThreads;
        if(nValuesSize < nThreads)
        {
            partial_accum.resize(1);
            BlockRange range;
            range.begin = begin;
            range.end = nValuesSize;
            range.id = 0;
            body(range,&partial_accum);
            return accumulate(partial_accum.begin(),partial_accum.end(),retType(0));
        }
        // building blocks
        vector<BlockRange> blocks;
        int index = begin;
        int blockId = 0;
        while(index <= nValuesSize)
        {
            BlockRange range;
            range.begin = index;
            range.end   = index+ perBlockSize;
            range.id    = blockId;
            blocks.push_back(range);
            index += (perBlockSize) ;
            blockId += 1;
        }
        partial_accum.resize(blocks.size());
    
        // fix last block end size;
        blocks[blocks.size()-1].end = nValuesSize;
        // thread pool to run
        typedef shared_ptr<thread> thread_ptr;
        vector<thread_ptr> pools;
    
        for(BlockRange&r:blocks)
        {
            pools.emplace_back(new thread(body,r,&partial_accum));
        }
        for(auto &t:pools)
        {
            t->join();
        }
    
        return accumulate(partial_accum.begin(),partial_accum.end(),retType(0));
    
    
    }
    
    
    void parallel()
    {
        vector<int> values(1000000000);
        fill(values.begin(),values.end(),1);
    
        double start,end,cost;
        start=clock();
        cout << "get the result :" <<parallel_add<int>(ApplyFoo(&values),values.size(),0) <<endl;
        end= clock();
        cost = end -start;
        cout << "parallel for cost time:" << cost <<endl;
    }
    
    void serial()
    {
        vector<int> values(1000000000);
        fill(values.begin(),values.end(),1);
    
        double start,end,cost;
        start=clock();
        cout << "get the result :" <<accumulate(values.begin(),values.end(),0) <<endl;
        end= clock();
        cost = end -start;
        cout << "parallel for cost time:" << cost <<endl;
    }
    
    
    int main()
    {
    
        parallel();
        //serial();
        return 0;
    }
    View Code

    <n> boost bind

    #include <boost/bind.hpp>
    #include <boost/shared_ptr.hpp>
    
    #include <iostream>
    using namespace std;
    void dprint(int x,int y)
    {
        cout << x << " " <<y <<endl;
    }
    
    class Bind_test
    {
    public:
        void setData(int x,int y)
        {
            _x = x;
            _y = y;
        }
        void printData()
        {
            cout << _x << " " <<_y <<endl;
        }
    private:
        int _x;
        int _y;
    
    };
    
    void increnum(int &dg)
    {
        dg++;
    }
    
    int main()
    {
        boost::bind(&dprint,5,5)(); // 5,5
        boost::bind(&dprint,3,_1)(4);  // 3, 5
        boost::bind(&dprint,_1,_1)(2);  // 2, 2
        boost::bind(&dprint,_1,_2)(1,2);  // 1, 2
        boost::bind(&dprint,_2,_1)(1,2);  // 2, 1 ->函数参数对掉
        
        cout << "
    bind the class function
    ";
        boost::shared_ptr<Bind_test> bclass(new Bind_test);
        boost::bind(&Bind_test::setData,bclass,1,2)();
        bclass->printData();
    
        Bind_test *bclass_02  = new Bind_test;
        boost::bind(&Bind_test::setData,bclass_02,2,3)();
        bclass_02->printData(); // 2 ,3
        delete  bclass_02;
    
    
        Bind_test bclass_03;
        boost::bind(&Bind_test::setData,&bclass_03,4,5)(); 
        bclass_03.printData(); // 4 ,5
        boost::bind(&Bind_test::setData,&bclass_03,_1,_1)(9); 
        bclass_03.printData(); // 9 ,9
        boost::bind(&Bind_test::setData,&bclass_03,_1,_2)(9,10); 
        bclass_03.printData(); // 9 ,10
    
    
        int dgNum = 0;
        boost::bind(&increnum,boost::ref(dgNum))(); // 类似C++11 Thread 里要传递引用std::ref(x)
        cout << dgNum <<endl;
    
    
    
        cin.get();
        return 0;
    }
    View Code

    额外的:

    static_assert 编译时候assertions

     

     下面将输出:hello no

    cout << R"(hello 
     no)" <<endl;

  • 相关阅读:
    HDOJ/HDU 1015 Safecracker(枚举、暴力)
    nodejs之入门
    git错误收集总结
    git基本操作
    git使用前配置
    花开花落花非花、缘起缘灭缘随缘
    js之定时器
    js之Date(日期对象)
    es5严格模式简谈
    try...catch
  • 原文地址:https://www.cnblogs.com/gearslogy/p/6083967.html
Copyright © 2020-2023  润新知