现代C++ moderncpp

#include <iostream>
#include <memory>
#include <string>

int main(int argc, char const *argv[])
{
    // ISO C++ forbids converting a string constant to ‘char*’
    char *p = "this is const string"; 
    char pStr[] = "this is test";

    // warning: ‘template<class> class std::auto_ptr’ is deprecated
    std::auto_ptr<std::string> pAuto( new std::string("hello"));

    //使用 unique_ptr 取代 auto_ptr
    std::unique_ptr<std::string> pUnique(new std::string("hellow"));


    //C语言风格的类型转换被弃用, static_cast、reinterpret_cast、const_cast 来进行类型转换。
    uint32_t *pInt = reinterpret_cast<uint32_t*>(new int(10));
    int *pTmpInt = new int(10);
    // uint32_t *pInt = static_cast<uint32_t*>(pTmpInt);


    return 0;
}


#include <iostream>
#include <stdio.h>

constexpr int fibonacci(const int n)
{
    //std::cout << n << std::endl;
    printf("%d\n", n);
    //return (1 == n || 2 == n) ? 1 : (fibonacii(n - 1) + fibonacii(n - 2));
    if(n == 1) return 1;
    if(n == 2) return 1;
    return fibonacci(n-1) + fibonacci(n-2);
}


int main(int argc, const char** argv) 
{
    int a[fibonacci(5)] = { 0 };
    int b[fibonacci(5)] = { 0 };
    return 0;
}

#include <iostream>
#include <type_traits>

void foo(char *) {
    std::cout << "foo(char*) is called" << std::endl;
}
void foo(int i) {
    std::cout << "foo(int) is called" << std::endl;
}


constexpr int fibonacii(const int n)
{
    std::cout << n << std::endl;
    return (1 == n || 2 == n) ? 1 : (fibonacii(n - 1) + fibonacii(n - 2));
}

int main(int argc, const char** argv) 
{
    if(std::is_same<decltype(NULL), decltype(0)>::value)
    {
        std::cout << "NULL == 0" << std::endl;
    }
    if (std::is_same<decltype(NULL), decltype((void*)0)>::value)
        std::cout << "NULL == (void *)0" << std::endl;
    if (std::is_same<decltype(NULL), std::nullptr_t>::value)
        std::cout << "NULL == nullptr" << std::endl;

    foo(0);
    // foo(NULL);  //编译失败
    foo(nullptr);


    // std::cout << fibonacii(5) << std::endl;
    int a[fibonacii(5)] = {0};

    return 0;
}

//yqq

#include <iostream>
#include <algorithm>
#include <vector>

using namespace std;
int main()
{
    std::vector<int> vctNums ({1, 2, 3, 4});
    auto it2 = std::find(vctNums.begin(), vctNums.end(), 2); //vctNums.find(2);
    if(vctNums.end() != it2)
    {
        *it2 = 4;
    }

    for_each(vctNums.begin(), vctNums.end(), [](int n){
        std::cout << n << std::endl;
    });


    std::cout << "------use c++17--------" << std::endl;
    // c++17 可以将在if语句中声明临时变量
    if(auto it = std::find(vctNums.begin(), vctNums.end(), 3 ); it != vctNums.end())
    {
        *it = 99;
    }
    
    std::for_each(vctNums.begin(), vctNums.end(), [](int n){
        std::cout << n << std::endl;
    }); 

    return 0;
}


//yqq

#include <iostream>
#include <algorithm>
#include <initializer_list>
#include <vector>

using namespace std;



class MyClass
{
private:
    std::vector<int> _m_vctNumber;

public:
    MyClass(std::initializer_list<int> list)
    {
        for(auto &item : list)
        {
            _m_vctNumber.push_back(item);
        }
    }

    void Show()
    {
        for(const auto &item: _m_vctNumber)
        {
            std::cout << item << std::endl;
        }
    }

};



int main()
{
    MyClass  mcl({1, 4, 9});
    mcl.Show();


    return 0;
}


//yqq

#include <iostream>
#include <algorithm>
#include <tuple>

using namespace std;

std::tuple<int, double, std::string> f() {
    return std::make_tuple(1, 2.3, "456");
}

int main()
{
    auto [x, y, z] = std::make_tuple(1, "sddd", 3.999);  //C++17 ok
    // auto [x, y, z] = f();
    std::cout << x << ", " << y << ", " << z << std::endl;

    return 0;
}


//yqq

#include <iostream>
#include <algorithm>

using namespace std;


template <typename Arg1, typename Arg2> 
auto add(Arg1 arg1, Arg2 arg2) -> decltype(arg1 + arg2)  //C++11
{
    return arg1 + arg2;
}

template <typename Arg1, typename Arg2>
auto add_cpp17(Arg1 arg1, Arg2 arg2)  // C++14 
{
    return arg1 + arg2;
}

template<typename T = int, typename U = int>
auto add_default(T x, U y) -> decltype(x+y) { //c++11   默认模板参数
    return x+y;
}

int main()
{
    auto r = add<int, double>(1, 1.234);
    auto r2 = add_cpp17<int, double>(1, 1.234);
    auto r3 = add_default(9, 20);
    std::cout << r << std::endl;
    std::cout << r2 << std::endl;
    std::cout << r3 << std::endl;
    return 0;
}


//yqq

#include <iostream>
#include <algorithm>

using namespace std;


template <typename T>
void PrintTypeInfo(T arg)
{
    if constexpr( std::is_integral<T>::value ) {
        re
    }

}

int main()
{


    return 0;
}


//yqq

#include <iostream>
#include <algorithm>
#include <vector>

using namespace std;


typedef int(*cbfunc)(int, int); //回调函数类型
using cbfuncex = int(*)(int, int);

using VCTINT = std::vector<int>;

int foo(int a, int b)
{
    return a + b;
}

void run( cbfunc func , int a, int b)
{
    std::cout << func(a, b) << std::endl;
}

int main()
{
    cbfunc  cb = foo;
    run(cb, 9, 10);

    cbfuncex cbex = foo;
    run(cbex, 10, 29);

    VCTINT a = {9, 2, 39, 10};
    for_each(a.begin(), a.end(), [](int n){
        std::cout << n << std::endl;
    });

    return 0;
}


//yqq

#include <iostream>
#include <algorithm>
#include <initializer_list>

using namespace std;


//变长模板参数


template<typename T>
void myprintf(T value)
{
    std::cout << value << std::endl;
}

template<typename T, typename... Args>
void myprintf(T value, Args... args)
{
    std::cout << value << std::endl;
    myprintf(args...);
}

template<typename T, typename... Args>
void myprintf2(T value, Args... args)
{
    std::cout << value << std::endl;

    // 如果还有, 继续递归
    if constexpr (sizeof...(args) > 0){ // C++17
        myprintf2(args...);
    }
}

template<typename T, typename... Args>
auto myprintf3(T value, Args... args)
{
    std::cout << value << std::endl;


    // 看不懂啥意思
    auto r = std::initializer_list<T>{( [&args] {
        std::cout << args << std::endl;
    }(), value)...};
    std::cout << "size is : " << r.size() << std::endl;
    std::cout << "initializer_list  is :" << std::endl;

    for_each(r.begin(), r.end(), [](T v){
        std::cout << v << std::endl;
    });
}

template <typename ... T>
auto Sum(T ... args)
{
    return (args + ...);
}


template <typename T, int nSize>
class MyBuf
{
public:
    virtual ~MyBuf(){}

private:
    T _m_data[nSize];
};



int main()
{
    myprintf(1, 2, "666", 234.9234, 'c', true);

    std::cout << "--------" << std::endl;
    myprintf2(1, 2, "666", 234.9234, 'c', true);
    std::cout << "--------" << std::endl;

    myprintf3(1, 2, "666", 234.9234, 'c', true);

    std::cout << "--------" << std::endl;
    std::cout <<"sum : " << Sum(9, 1, 99, 1.123) << std::endl;


    MyBuf<int, 100> buf;
    std::cout << "sizeof(buf) is " << sizeof(buf) << std::endl;

    std::cout <<"sizeof(char *) is " <<  sizeof(char *) << std::endl;
    std::cout << "sizeof(int): " << sizeof(int) << std::endl;
    std::cout << "sizeof(short): " << sizeof(short) << std::endl;
    std::cout << "sizeof(long): " << sizeof(long) << std::endl;
    std::cout << "sizeof(long long): " << sizeof(long long) << std::endl;
    std::cout << "sizeof(float): " << sizeof(float) << std::endl;
    std::cout << "sizeof(double): " << sizeof(double) << std::endl;


    return 0;
}


//yqq

#include <iostream>
#include <algorithm>
#include <string>
using namespace std;



enum class RGB : unsigned int{ 
    RED = 0x0,
    GREEN = 0xff,
    BLUE = 0xffff,
};

enum class  HHH { 
    RED = 0x0,
    GREEN = 0xff,
    BLUE = 0xffff,
};

enum class MAP : int {
    FIRST = -1,
    SECOND = -999,
    THRID  = 19900
};


template<typename T>
std::ostream& operator<< (typename std::enable_if<std::is_enum<T>::value, std::ostream>::type& stream, const T& e)
{
    return stream << static_cast<typename std::underlying_type<T>::type>(e);
}



int main()
{
    // if(RGB::RED == HHH::BLUE) // 编译不过
    if(RGB::RED == RGB::BLUE)
    {
        std::cout << "RGB::RED == RGB::BLUE" << std::endl;
    }
    std::cout << MAP::THRID << std::endl;


    return 0;
}


//yqq

#include <iostream>
#include <algorithm>

using namespace std;


class Base
{
public:
    int _m_v1;
    int _m_v2;

    Base()
    {
        _m_v1 = 1;
    }

    Base(int n) : Base() //C++11 委托构造
    {
        _m_v2 = n;
    }

    virtual void FinalFunc() final
    {
        std::cout << "this is final function" << std::endl;
    }

};


class Sub : public Base
{
public:
    int _m_v3;
    Sub(int v3):Base(2)
    {
        _m_v3 = v3;
    }

    // virtual void FinalFunc() 
    // {
    //    std::cout << "override final function" << std::endl; 
    // }

    
public:
    using Base::Base;
};


class MyClass
{
public:
    MyClass() = default;
    MyClass& operator=(const MyClass& ) = delete;
    MyClass(int n) {std::cout << n << std::endl; };
};


int main()
{
    Base b(9);

    std::cout << b._m_v1 << std::endl;
    std::cout << b._m_v2 << std::endl;


    Sub s(9);
    std::cout <<" ---------" << std::endl;
    std::cout << s._m_v1 << std::endl;
    std::cout << s._m_v2 << std::endl;
    std::cout << s._m_v3 << std::endl;
    std::cout <<" ---------" << std::endl;

    MyClass mcls(99);

    return 0;
}


#include <iostream>
template<typename ... T>
auto average(T ... t) {
    return (t + ... ) / sizeof...(t);
}
int main() {
    std::cout << average(1, 2, 3, 4, 5, 6, 7, 8, 9, 10) << std::endl;
}

#include <iostream>
#include <map>
#include <string>
#include <functional>

template <typename Key, typename Value, typename F>
void update(std::map<Key, Value>& m, F foo) {
    for (auto&& [key, value] : m ) value = foo(key);
}

int main() {
    std::map<std::string, long long int> m {
        {"a", 1},
        {"b", 2},
        {"c", 3}
    };
    update(m, [](std::string key) -> long long int {
        return std::hash<std::string>{}(key);
    });
    for (auto&& [key, value] : m)
        std::cout << key << ":" << value << std::endl;
}

//yqq

#include <iostream>
#include <algorithm>
// #include <utility>
#include <memory>
using namespace std;

int main()
{
    int value = 1;

    // 值捕获 与参数传值类似,值捕获的前提是变量可以拷贝,
    // 不同之处则在于,被捕获的变量在 lambda
    // 表达式被创建时拷贝,而非调用时才拷贝
    auto foo = [=] {  // 
        return value;
    };

    value = 9;
    auto value2  = foo();
    std::cout << "value = " << value << std::endl;
    std::cout << "value2 = " << value2 << std::endl;


    int  a = 0;
    auto func = [a](int v) {
        v = a + 1;
        return v;
    };
    auto b = func(a);
    auto c = a;
    std::cout << "b = " << b << std::endl;  // 1
    std::cout << "c = " << c << std::endl;  // 0


    int x  = 0;
    auto fun = [&x](int n) -> int&{
        x += 1 + n;
        return x;
    };
    x++; 
    auto y = fun(x); 
    auto& z = fun(x); 
    y++; 
    z++; 
    std::cout << "x = " << x << std::endl;  
    std::cout << "y = " << y << std::endl; 
    std::cout << "z = " << z << std::endl;  


    auto ptr = std::make_unique<int>(9);
    auto add = [v1 = 1, v2 = std::move(ptr)](int x, int y) {
    // auto add = [v1 = 1, v2 = ptr](int x, int y) { // error unique_ptr 不可拷贝
        return x + y + v1 + (*v2);
    };
    std::cout << add(9, 10) << std::endl;



    auto f = [](auto x, auto y) -> auto { //C++14
        return x + y;
    };
    std::cout << f(9, 2) << std::endl;


    return 0;
}


//yqq

#include <iostream>
#include <algorithm>
#include <functional>

using namespace std;


int foo(int n)
{
    return n;
}

void increase(int & v) {
    v++;
}

int main()
{
    std::function<int(int)> f = foo;
    std::cout << f(9) << std::endl;

    std::function<int(int)> func = [d = 9](int value) -> int {
        return d + value;
    };
    std::cout << func(9) << std::endl;


    auto add  = [](auto a, auto b, auto c) -> auto{
        return a + b + c;
    };

    auto bf = std::bind(add, std::placeholders::_1, 100, 200 );
    std::cout << bf(80) << std::endl;


    // double s = 1;
    // increase(s);

    return 0;
}


//yqq

#include <iostream>
#include <algorithm>
#include <string>
using namespace std;



class MyClass
{
private:
    /* data */
    int *_m_pData;
    std::string  _m_strName;
public:

    MyClass(const std::string  &strName)
    :_m_pData(new int(10)), _m_strName(strName)
    {
        std::cout << "construct " << _m_strName << std::endl;
    }

    MyClass(MyClass& rhs):
         _m_pData(new int(*(rhs._m_pData))),
        _m_strName(rhs._m_strName)
    {
        std::cout <<  "copy " << rhs._m_strName << std::endl;
    }

    MyClass(MyClass&& r_rhs): 
        _m_strName(r_rhs._m_strName),
        _m_pData(r_rhs._m_pData)
    {
        std::cout << " moved " << r_rhs._m_strName << std::endl;
        r_rhs._m_pData = nullptr;
        r_rhs._m_strName.clear();
    }

    ~MyClass()
    {
        std::cout << _m_strName <<  " ~MyClass() " << std::endl;
        delete _m_pData;
    }
};

// MyClass  foo(bool flag)
MyClass  foo(bool flag)
{
    //将亡值 (xvalue, expiring value),
    //是 C++11 为了引入右值引用而提出的概念(因此在传统 C++
    //中,纯右值和右值是同一个概念),也就是即将被销毁、却能够被移动的值。
    // 移动了之后, 将忘值还是会销毁,
    // 
    // 这也解释了为什么会有 3 次析构

    MyClass  objA("A"), objB("B");
    if(flag) {
        std::cout << "a" << std::endl;
        return objA;
    } 
    else {
        std::cout << "b" << std::endl;
        return objB;
    }
}

/*
函数形参类型    实参参数类型    推导后函数形参类型
T&              左引用          T&
T&              右引用          T&
T&&             左引用          T&
T&&             右引用          T&&
*/

//无论模板参数是什么类型的引用,当且仅当实参类型为右引用且形参类型为右引用时,
//模板参数才能被推导为右引用类型。

int main()
{
    MyClass  a = foo(true);
    std::cout << "obj: "  << std::endl;

    return 0;
}



//yqq

#include <iostream>
#include <algorithm>
#include <array>
#include <list>
#include <forward_list>

using namespace std;

int main()
{

    std::array<int, 4> arr = {1, 2, 4, 5};
    if( arr.empty() )
    {
        std::cout << "is empty" << std::endl;
    }

    std::cout << "size : " << arr.size() << std::endl;


    for(auto &item : arr)
    {
        std::cout << item << std::endl;
    }



    std::forward_list<std::string>  flstStrings;
    flstStrings.push_front("hello1");
    flstStrings.push_front("hello2");
    flstStrings.push_front("hello3");
    flstStrings.push_front("hello4");

    for(auto item : flstStrings)
    {
        std::cout << item << std::endl;
    }




    std::sort(arr.begin(), arr.end(), [](int a, int b) -> bool {
        return a > b; // > : 大的在前   < : 小的在前
    });
    std::for_each(arr.begin(), arr.end(), [](int n){
        std::cout <<  n  << " \t ";
    });
    std::cout << std::endl;
    
    


    return 0;
}


//yqq

#include <iostream>
#include <algorithm>
// #include <unordered_map>
#include <unordered_map>
#include <unordered_set>

using namespace std;


//  std::map / std::multimap / std::set / std::multiset   内部使用红黑树, 内部会进行排序  , 插入和搜索的时间复杂度为  O(log(n))
//  std::unordered_map / std::unordered_multimap  / std::unordered_set / std::unordered_multiset   是用 HashTable 实现,  插入和搜索的时间复杂度为  O(1)



int main()
{

    std::unordered_map<std::string, std::string>   mapInfo;
    mapInfo.insert( std::make_pair("boy1", "joke"));
    mapInfo.insert( std::make_pair("boy2", "Kobe"));
    mapInfo.insert( std::make_pair("boy3", "Map"));


    std::for_each(mapInfo.begin(), mapInfo.end(), [](auto item){ // C++14 支持自动推导
        std::cout <<  item.first  << " : " << item.second << std::endl;
    });


    std::unordered_multimap<std::string, std::string> mapMulMap; 
    mapMulMap.insert( std::make_pair("boy1", "joke"));
    mapMulMap.insert( std::make_pair("boy1", "Kobe"));
    mapMulMap.insert( std::make_pair("boy1", "Map"));
    std::for_each(mapMulMap.begin(), mapMulMap.end(), [](auto item){ // C++14 支持自动推导
        std::cout <<  item.first  << " : " << item.second << std::endl;
    });

    return 0;
}


//yqq

#include <iostream>
#include <algorithm>
#include <any>  //c++17
#include <string>

using namespace std;


int main()
{

    std::any  a = 9;
    std::cout << std::any_cast<int>(a) << std::endl;

    a  = std::string("this is a");
    std::cout << std::any_cast<std::string>(a) << std::endl;


    a.reset(); //删除a 中的值
    if( a.has_value())
    {
        std::cout << "a 中有值" << std::endl;
    }
    else
    {
        std::cout << "a 中无值" << std::endl;
    }
    


    return 0;
}


//yqq

#include <iostream>
#include <algorithm>
#include <tuple>
#include <variant> // C++17

using namespace std;

template <size_t n, typename... T>
constexpr std::variant<T...> _tuple_index(const std::tuple<T...> &tpl, size_t i)
{
    if constexpr (n >= sizeof...(T))
        throw std::out_of_range(" 越界.");
    if (i == n)
        return std::variant<T...>{std::in_place_index<n>, std::get<n>(tpl)};
    return _tuple_index<(n < sizeof...(T) - 1 ? n + 1 : 0)>(tpl, i);
}

template <typename... T>
constexpr std::variant<T...> tuple_index(const std::tuple<T...> &tpl, size_t i)
{
    return _tuple_index<0>(tpl, i);
}

template <typename T0, typename... Ts>
std::ostream &operator<<(std::ostream &s, std::variant<T0, Ts...> const &v)
{
    std::visit([&](auto &&x) { s << x; }, v);
    return s;
}


int main(int argc, char* argv[])
{

    std::variant<float, double, std::string, int>  vars;
    vars = 9;
    std::visit([&](auto &&x) { std::cout << x << std::endl;}, vars  );

    std::tuple<std::string, double, double, int> t("123", 4.5, 6.7, 8);
    int i = argc;
    std::cout << tuple_index(t, i) << std::endl;
    return 0;
}


//yqq

#include <iostream>
#include <algorithm>
#include <variant>
#include <valarray>
#include <iomanip>

using namespace std;



union MyUnion
{
    int i;
    float f;
    // std::string  str;
    char ch;
};


// 使用 std::variant 实现函数返回多个不同类型的值

using Two = std::pair<double, double>;
//using Roots = std::variant<Two, double, void*>;
// using Roots = std::variant<Two, double, void *>;
using Roots = std::variant<Two, double>;

Roots FindRoots(double a, double b, double c)
{
    auto d = b*b-4*a*c;

    if (d > 0.0)
    {
        auto p = sqrt(d);
        return std::make_pair((-b + p) / 2 * a, (-b - p) / 2 * a);
    }
    else if (d == 0.0)
        return (-1*b)/(2*a);
    // return nullptr;
    return 0.0;
}

struct RootPrinterVisitor
{
    void operator()(const Two& roots) const
    {
        std::cout << "2 roots: " << roots.first << " " << roots.second << '\n';
    }
    void operator()(double root) const
    {
        std::cout << "1 root: " << root << '\n';
    }
    void operator()(void *) const
    {
        std::cout << "No real roots found.\n";
    }
};



int main()
{
    double pi = 3.14159265359;
    const int nSize = 10;
    std::valarray<double>  vctFloats(nSize);
    for(int i = 0; i < nSize; i++)
    {
        vctFloats[i] = 0.25 * i - 1;
    }

    for(int i = 0; i < nSize; i++)
    {
        std::cout << " " << vctFloats[i];
    }
    std::cout << std::endl;



    std::valarray<double> vctFloats2(nSize);
    // vctFloats2 = sin(vctFloats);
    vctFloats2 = acos(vctFloats);

    for (int i = 0 ; i < nSize ; i++ )
    {
      cout << setw(10) << vctFloats2 [ i ]
         << "  radians, which is  "
         << setw(11) << (180/pi) * vctFloats2 [ i ]
         << "  degrees" << endl;
    }


    std::variant<int, float, std::string>  var;
    var =  std::string("hello");
    std::cout << std::get<std::string>(var) << std::endl;  // C++17

    var = (float)0.9999;
    std::cout << std::get<float>(var) << std::endl;


    var = (int) 999;
    std::cout << std::get<int>(var) << std::endl;
    // std::cout << std::get<float>(var) << std::endl; // error
    // std::cout << std::get<std::string>(var) << std::endl;  // error


    // MyUnion  u =  {std::string("string")};
    MyUnion u;
    std::cout << "sizeof(MyUnion) = " << sizeof(MyUnion) << std::endl;
    u.f = 999.999;
    std::cout << u.f << std::endl;
    u.i = 999;
    std::cout << u.i << std::endl;
    // u.str = std::string("hello");
    // std::cout << u.str << std::endl;
    u.ch = 'z';
    std::cout << u.ch << std::endl;
    std::cout << u.f<< std::endl;
    std::cout << u.i<< std::endl;


    // std::visit(RootPrinterVisitor(), FindRoots(1, -2, 1)); // ok
    /*
    std::visit( [&](auto&& x){
        if(std::holds_alternative<Two>(x))
        {
            std::cout << "two roots: " << x.first << ", " << x.second << std::endl;
        }
        else if(std::holds_alternative<double>(x))
        {
            std::cout << "one root: " << x << std::endl;
        }
        // else if(std::holds_alternative<void *&>(x))
        // {
        //     std::cout << "no root" << std::endl;
        // }
        else
        {
            std::cout << "error type" << std::endl;
        }
    }, FindRoots(1, -2, 1));
    */



    return 0;
}


//yqq

#include <iostream>
#include <algorithm>
#include <string>
#include <memory>

using namespace std;

// std::shared_ptr/std::unique_ptr/std::weak_ptr

void foo(std::shared_ptr<std::string> &sp)
{
    *sp += std::string("good");
}


// 循环引用
struct A;
struct B;

struct A
{
    std::shared_ptr<B> pointer;
    // std::weak_ptr<B> pointer;
    A(){std::cout << "A 构造" << std::endl;}
    ~A()
    {
        std::cout << "A 被销毁" << std::endl;
    }
};
struct B
{
    std::shared_ptr<A> pointer;
    // std::weak_ptr<A> pointer;
    B(){std::cout << "B 构造" << std::endl;}
    ~B()
    {
        std::cout << "B 被销毁" << std::endl;
    }
};

int main()
{

    std::shared_ptr<std::string> sp = std::make_shared<std::string>("hello");
    // sp.get();
    std::cout << *sp << std::endl;
    // auto ssp = sp;
    foo(sp);
    std::cout << *sp << std::endl;

    std::unique_ptr<std::string> up = std::make_unique<std::string>("hello"); // c++14

    /*
    // unique_ptr  禁用了 拷贝构造  和  赋值运算符重载
      unique_ptr(const unique_ptr&) = delete;
      unique_ptr& operator=(const unique_ptr&) = delete;
    */
    // auto uup =  up;

    auto a = std::make_shared<A>();
    auto b = std::make_shared<B>();
    a->pointer = b; 
    //b 的引用计数变为 2
    b->pointer = a;
    //a 的引用计数变为 2

    return 0;
} // a , b 的引用计数减 1, 


//yqq

#include <iostream>
#include <algorithm>
#include <string>
#include <regex>

using namespace std;

int main()
{

    std::string fnames[] = {"foo.txt", "bar.txt", "test", "a0.txt", "AAA.txt"};

    //std::regex txt_regex("[a-z]+\\.txt");
    std::regex txt_regex(R"([a-z]+\.txt)"); // C++11 的原生字符串
    for (const auto &fname: fnames)
    {
        std::cout << fname << ": " << std::regex_match(fname, txt_regex) << std::endl;
    }


    


    return 0;
}


//yqq

#include <iostream>
#include <algorithm>
#include <string>
#include <future>
#include <thread>
#include <cmath>
#include <chrono>
using namespace std;


//辗转相除法求最大公约数函数
int gcd(int a, int b) {
	int temp;

	//比较两个数的大小,值大的数为a,值小的数为b
	if (a < b) {
		temp = a;
		a = b;
		b = temp;
	}

	//求余
	while (b != 0) {
		temp = a % b;
		a = b;
		b = temp;
	}
	return a;
}


int main()
{
    std::packaged_task<double ( double )> task([](double n)->double {
        std::this_thread::sleep_for(std::chrono::seconds(10));
        return sqrt(n); 
    });


    // std::function<>
    //std::packaged_task<int (int, int)> gcdTask([](int, int));
    std::packaged_task<int (int, int)>  gcdTask(gcd);

    std::future<double> result = task.get_future();
    std::future<int> gcdResult = gcdTask.get_future();
    std::thread(std::move(gcdTask), 23782349, 7282335).detach();

    std::thread(std::move(task), 9.9234).detach();
    std::cout << "do othering" << std::endl;
    for(int i = 0; i < 100; i++)
    {
        double sum = i * 3.1234234329;
        std::cout << sum << std::endl;
        //std::this_thread::sleep_for(std::chrono::milliseconds(10));
    }

    std::cout << "gcd result: " << gcdResult.get() << std::endl;

    std::cout << "get result" << std::endl;
    if( result.valid())    
    {
        std::cout << "result is valid" << std::endl;
        std::cout << "result is :" << result.get() << std::endl;  // get() 会阻塞等待, 知道结果返回
    }
    else
    {
        std::cout << "result is invalid" << std::endl;
    }
    


    return 0;
}


//yqq

#include <iostream>
#include <algorithm>
#include <string>
#include <thread>
#include <future>
#include <vector>
#include <cmath>

using namespace std;

std::vector<uint64_t> PrimeFacotrization(uint64_t n)
{
    std::vector<uint64_t> vctFactors;
    for (uint64_t i = 2; i <= sqrt(n); i++)
    {
        if (n % i == 0)
        {
            //printf("%llu  ", i);
            vctFactors.push_back(i);
            vctFactors.push_back( n / i );
        }
          
    }
    return std::move(vctFactors);
}

int main(int argc, char *argv[])
{
    if(argc < 2)
    {
        std::cout << "usage   ./a.out  number" << std::endl;
        return 0;
    }

    uint64_t  num = atoll(argv[1]);
    std::future<std::vector<uint64_t> >  result = std::async(PrimeFacotrization, num);

    PrimeFacotrization(num * 2);

    std::cout << "开始获取 aysnc函数的返回值" <<  std::endl;
    auto factors = result.get();
    std::for_each(factors.begin(), factors.end(), [](uint64_t n ){
        std::cout << n  << " ";
    });
    std::cout << std::endl;

    

    return 0;
}



// //yqq

// #include <iostream>
// #include <algorithm>
// #include <string>
// #include <thread>
// #include <mutex>
// #include <condition_variable>
// #include <queue>
// #include <random>
// #include <chrono>
// #include <future>
// #include <atomic>
// // #include <boost/lockfree/queue.hpp> 

// using namespace std;

// int main()
// {

//     std::queue<double>   qMsgs;
//     std::condition_variable cv;
//     std::mutex  mtx;
//     // std::atomic_bool atomIsFull;
//     // std::atomic_bool atomIsEmpty; 


//     const int nConsumers = 5;
//     const int nProducer = 3;

//     auto producer = [&](){
//         std::default_random_engine  e;
//         // std::uniform_int_distribution<int> ud(e);
//         std::normal_distribution<> nd(-2342.234932, 99999.999924);
//         while(true)
//         {
//             {
//             std::cout << " producer[" << std::this_thread::get_id() << "] producing one item" << std::endl;
//             std::unique_lock<std::mutex> lock(mtx);
//             for(int i = 0; i < nConsumers; i++)
//             {
//                 qMsgs.push(nd(e));
//             }
//             //cv.notify_one();
//             cv.notify_all();
//             atomItemCount ++;
//             }
            
//             std::this_thread::sleep_for(std::chrono::milliseconds(100));
//         }
//     };

//     auto consumer = [&]() {
//         std::cout << "thread " << std::this_thread::get_id() << "  started"  << std::endl;
//         while(!qMsgs.empty())
//         {
//             {
//             std::unique_lock<std::mutex>  lock(mtx);
//             // while( !atomIsFull && !atomIsEmpty  )
//             {
//                 cv.wait(lock);
//             }
//             std::cout <<  " consumer[" << std::this_thread::get_id() \
//                 << "] consuming: " <<  qMsgs.front()  << std::endl;
//             qMsgs.pop();
            
//             }
//             std::this_thread::yield();
           
//             // std::this_thread::sleep_for(std::chrono::milliseconds(100));
//         }
//     };


//     auto proFuture = std::async(producer);
//     std::vector<decltype(proFuture)> vctPros;
//     vctPros.push_back( std::move(proFuture) );
//     for(int i = 0; i < nProducer - 1; i++  )
//     {
//         vctPros.push_back(std::move( std::async(producer)  ));
//     }


//     auto f =  std::async(consumer);
//     std::vector<decltype(f)> vctFutures;
//     vctFutures.push_back(std::move(f));
//     for(int i = 0; i < nConsumers - 1; i++)
//     {
//         vctFutures.push_back(std::move(std::async(consumer) ));
//     }

//     while(true)
//     {
//         std::cout << "main thread  " << std::endl;
//         std::this_thread::sleep_for(std::chrono::seconds(10));
//     }

//     return 0;
// }


//yqq

#include <iostream>
#include <algorithm>
#include <string>
#include <boost/lockfree/spsc_queue.hpp>
#include <boost/thread/thread.hpp>
#include <boost/container/vector.hpp>
#include <boost/thread/future.hpp>
#include <boost/random.hpp>
#include <boost/move/move.hpp>
#include <boost/container/deque.hpp>
// #include <boost/thread/a
#include <boost/thread/mutex.hpp>

using namespace std;

// void foo()
// {
//     for (int i = 0; i < 10; i++)
//     {
//         std::cout << "sub thread" << std::endl;
//     }
// }


int main()
{
    using boost::thread;
    using boost::container::vector;
    // using boost::
    // using boost::lockfree::queue ;
    using boost::lockfree::spsc_queue;
    // using boost::move;
    // using boost::random;

    spsc_queue<double> lockfreeQueue(100000000);
    // boost::container::deque<double> lockfreeQueue;
    const int cnProducer = 10, cnConsumer = 10;

    boost::mutex  mtx;

    vector<thread> vctProducer;
    const double pi = 3.14159261314;

    for (int i = 0; i < cnProducer; i++)
    {
        vctProducer.push_back( boost::move( thread([&pi, &lockfreeQueue, &mtx]() {
            for (int i = 0; i < 10000000; i++)
            {
                // std::cout << "sub thread" << std::endl;
                lockfreeQueue.push( pow(i, 3) * pi / 2  );

                // boost::lock_guard<boost::mutex>  lock(mtx);
                // lockfreeQueue.push_back( pow(i, 3) * pi / 2  );
            }
        })));
    }

    for(auto &thd : vctProducer)
    {
        thd.join();
    }


    return 0;
}


// g++ 7_5_boost_lockfree_queue.cpp -lpthread -lboost_thread

#include <boost/thread/thread.hpp> 
#include <iostream> 

void hello() 
{ 
    std::cout <<         "Hello world, I''m a thread!"  << std::endl; 
} 

int main(int argc, char* argv[]) 
{ 
    boost::thread thrd(&hello); 
    thrd.join(); 
    return 0; 

}

现代C++程序设计(原书第2版)》图文并茂,通俗易懂,真正做到寓教于乐,是一本难得的C++面向对象设计入门教材。 出版者的话 译者序 前言 第1章 C++概述与软件开发 1.1 什么是C语言和C++ 1.1.1 C和C++历史回顾 1.1.2 C/C++是一门编译语言 1.1.3 为什么许多程序员都选择C++ 1.2 什么是面向对象 1.2.1 C++程序并不一定是面向对象的 1.2.2 一个简单的面向对象程序示例 1.2.3 面向对象的软件更有优势 1.3 结构化设计与面向对象设计 1.3.1 ATM——结构化设计 1.3.2 采用面向对象方法的ATM——究竟是谁的任务 1.3.3 汽车维护——结构化设计 1.3.4 采用面向对象方法的汽车维护——究竟是谁的任务 1.4 软件开发技术概述 1.5 问题发现与解决 复习题 第2章 C++的入门知识 2.1 编程基础 2.1.1 算法设计 2.1.2 正确的软件开发步骤 2.2 专业术语及工程创建 2.3 C++程序的一般格式 2.3.1 “Hello World!”程序 2.3.2 “How’s the Weather?”程序 2.4 程序的数据及数据类型 2.4.1 C++的数据类型 2.4.2 容器=数据类型,标签=变量名 2.4.3 数据类型修饰符 2.4.4 问题分析:整型数据究竟有多大 2.5 C++中的变量声明 2.5.1 C++的命名规则 2.5.2 在哪里声明变量 2.6 C++中的运算符 2.6.1 计算路程的程序 2.6.2 从键盘输入程序所需数据 2.6.3 赋值运算符 2.6.4 运算符的优先级 2.6.5 数据类型及其存储的值 2.6.6 算术运算符 2.6.7 自增运算符和自减运算符 2.6.8 复合赋值运算符 2.7 #define、const和数据类型转换 2.7.1 #define预处理指令 2.7.2 const修饰符 2.7.3 const比#define好吗 2.7.4 数据类型转换 2.8 关于键盘输入和屏幕输出的更多内容 2.8.1 转义序列 2.8.2 ios格式标记 2.8.3 流的IO控制符 2.9 开始使用类和对象、C++string类 2.10 练习 复习题 第3章 控制语句和循环 3.1 关系运算符和逻辑运算符 3.2 if语句 3.2.1 if-else语句 3.2.2 问题分析:在if语句中使用大括号 3.2.3 if-else if-else语句 3.2.4 低效的编程方法 3.2.5 if-else程序示例 3.2.6 嵌套if-else语句 3.2.7 条件运算符“?” 3.3 switch语句 3.4 循环 3.4.1 括号的用法 3.4.2 无限循环 3.5 for循环 3.5.1 不要改变循环索引 3.5.2 for循环示例 3.6 while循环 3.7 do while循环 3.8 跳转语句 3.8.1 break语句 3.8.2 continue语句 3.9 问题发现与解决 3.9.1 五个常见错误 3.9.2 调试程序 3.10 C++类与vector类 3.11 总结 3.12 练习 复习题 第4章 函数一:基础 4.1 C++中的函数 4.1.1 只由一个main函数构成的程序 4.1.2 包含多个函数的程序 4.1.3 函数是个好东西 4.1.4 三个重要的问题 4.2 函数:基本格式 4.3 函数的编写要求 4.3.1 你想住在C++旅馆中吗 4.3.2 函数为先 4.3.3 函数声明或函数原型 4.3.4 函数定义、函数标题行与函数体 4.3.5 函数调用 4.3.6 传值调用 4.3.7 问题分析:未声明的标识符 4.4 重载函数 4.5 具有默认输入参数列表的函数 4.6 局部变量、全局变量和静态变量 4.6.1 局部变量 4.6.2 块范围 4.6.3 全局变量 4.6.4 危险的全局变量 4.6.5 问题分析:全局变量y0、y1与cmath 4.6.6 静态变量 4.7 C++stringstream类 4.8 总结 4.9 练习 复习题 第5章 函数二:变量地址、指针以及引用 5.1 数据变量和内存 5.1.1 sizeof运算符 5.1.2 预留内存 5.1.3 计算机内存和十六进制 5.2 取地址运算符& 5.3 指针 5.4 函数、指针以及间接运算符 5.4.1 解决思路 5.4.2 指针和函数 5.4.3 有效处理大型数据 5.5 函数和引用 5.5.1 复习:两种机制 5.5.2 为什么要强调指针的重要性 5.6 queue类 5.7 总结 5.8 练习 复习题 第6章 数组 6.1 使用单个数据变量 6.2 数组基础 6.2.1 数组的索引值从0开始 6.2.2 使用for循环和数组来实现的电话账单程序 6.2.3 数组的声明和初始化 6.2.4 数组越界==严重的问题 6.2.5 vector与数组的比较 6.3 数组和函数 6.3.1 每个数组都有一个指针 6.3.2 数组指针 6.3.3 向函数传递数组:最开始的引用调用 6.3.4 利用数组和函数生成随机数并进行排序 6.4 C字符串,也称为字符数组 6.4.1 字符数组的初始化 6.4.2 null字符 6.4.3 C字符串的输入 6.4.4 C++中提供的字符数组函数 6.5 多维数组 6.5.1 二维数组的初始化 6.5.2 嵌套的for循环和二维数组 6.5.3 利用二维数组来实现Bingo游戏 6.6 多维数组和函数 6.6.1 改进的Bingo卡片程序 6.6.2 白雪公主:利用二维数组来存储姓名 6.7 利用数据文件对数组赋值 6.8 总结 6.9 练习 复习题 第7章 类和对象 7.1 我们所了解的类和对象 7.2 编写自己的类 7.2.1 入门实例:自定义日期类 7.2.2 第一个C++类:Date类 7.2.3 揭开类的生命之谜 7.2.4 set和get函数的作用与VolumeCalc类 7.2.5 PICalculator类 7.3 作为类成员的对象 7.4 类的析构函数 7.5 对象数组 7.6 重载运算符与对象 7.7 指针、引用和类 7.7.1 指针和引用实例 7.7.2 处理日期和时间的程序实例 7.8 总结 7.9 练习 复习题 第8章 继承和虚函数 8.1 为什么继承如此重要 8.1.1 IceCreamDialog实例 8.1.2 Counter类实例 8.2 继承基础 8.2.1 Counter和DeluxeCounter实例 8.2.2 保护成员 8.2.3 员工、老板和CEO 8.3 访问控制符的规范和多继承 8.4 继承、构造和析构 8.4.1 构造函数和析构函数回顾 8.4.2 基类和派生类的默认构造函数——没有参数 8.4.3 在重载的构造函数中使用参数 8.4.4 基类和派生类的析构函数 8.4.5 医生也是人 8.4.6 关于派生类和基类构造函数的规则 8.5 多态和虚函数 8.5.1 多态——同一个接口,不同的行为 8.5.2 什么是虚函数 8.5.3 虚函数的作用 8.6 总结 8.7 练习 复习题 附录A 学习使用Visual C++2005Express Edition 附录B C++关键字表 附录C C++运算符 附录D ASCII码 附录E 位、字节、内存和十六进制表示 附录F 文件输入/输出 附录G 部分C++类 附录H 多文件程序 附录I Microsoft visual C++2005Express Edit
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值