c++ 11 심도 있는 응용 학습

9413 단어
C++11은 프로그램을 더욱 간결하고 우아하게 한다
호출 가능 대상
  • 는 함수 바늘
  • 이다
  • operator() 구성원 함수를 가진 클래스 대상(모조 함수)
  • 는 함수 바늘로 바꿀 수 있는 클래스 대상
  • 는 하나의 클래스의 구성원(함수) 지침
  • 이다.
    void func()
    {
    
    }
    
    struct Foo
    {
        void operator()(void)
        {
            
        }
    };
    
    struct Bar
    {
        using fr_t = void(*)(void);
        static void func(void)
        {
        }
        
        operator fr_t(void)
        {
            return func;
        }
    };
    
    struct A
    {
        int a_;
        void mem_func(void)
        {
        }
    };
    
    int main()
    {
        void(*func_ptr)(void) = &func;            //    
        func_ptr();
    
        Foo foo;                                                        //   
        foo();    
        
        Bar bar;
        bar();                                                             //              
    
        void(A::*mem_func_ptr)(void) = &A::mem_func;        //       
        int A::*mem_obj_ptr = &A::a_;                                            //     
    
        A aa;
        (aa.*mem_func_ptr)();
        aa.*mem_obj_ptr = 123;
    
        return 0;
    }

    std::function
      std::function은 호출 가능한 대상의 패키지입니다. 클래스 구성원 (함수) 바늘을 제외한 모든 호출 가능한 대상을 수용할 수 있습니다.템플릿 매개 변수를 지정하면 함수, 함수 대상, 함수 바늘을 통일된 방식으로 처리하고, 이를 저장하고 지연시킬 수 있습니다.
    #include 
    #include 
    
    using namespace std;
    
    void func(void)
    {
        std::cout << __FUNCTION__ << std::endl;
    }
    
    class Foo
    {
    public:
        static int foo_func(int a)
        {
            std::cout << __FUNCTION__ << std::endl;
            return a;
        }
    };
    
    class Bar
    {
    public:
        void operator()(void)
        {
            std::cout << __FUNCTION__ << std::endl;
        }
    };
    
    class A
    {
        std::function callback_;
    public:
        A(const std::function& f):callback_(f)
        {
            
        }
    
        void notify(void)
        {
            callback_();
        }
    };
    
    void call_when_even(int x, const std::function& f)
    {
        if(!(x & 1))
        {
            f(x);
        }
    }
    
    void output(int x)
    {
        std::cout << x << " ";
    }
    
    int main()
    {
        std::function fr1 = func;           //    
        fr1();
    
        std::function fr2 = Foo::foo_func;    //        
        std::cout << fr2(123) << std::endl;
    
        Bar bar;                                        //   
        fr1 = bar;
        fr1();
    
        A aa(bar);
        aa.notify();
    
        for (size_t i = 0; i < 10; i++)
        {
            call_when_even(i, output);
        }
        std::cout << std::endl;
        
        return 0;
    }

    std::bind
      std::bind는 호출 가능한 대상을 매개 변수와 함께 귀속시키는 데 사용됩니다.귀속된 결과는 std::function으로 저장할 수 있으며, 우리가 필요로 할 때 호출을 지연시킬 수 있습니다
  • 호출 가능한 대상을 매개 변수와 함께 모조 함수로 연결
  • 다원(파라미터 개수 n, n>1) 호출 대상을 일원 또는 (n-1)원 호출 대상, 즉 부분 파라미터만 귀속
  • class B
    {
    public:
        std::string name_;
        void output(int x, int y)
        {
            std::cout << x << " " << y << std::endl;
        }
    };
    
    int main()
    {
        B b;
        std::function fr = std::bind(&B::output, &b, std::placeholders::_1, std::placeholders::_2);
        fr(1,2);
    
        std::function<:string> fr_s = std::bind(&B::name_, &b);
        fr_s() = "hello";
    
        std::cout << b.name_ << std::endl;
        
        return 0;
    }

    후면 반환 유형
    template 
    //decltype(t+u) add(T t, U u)                       //C++         ,              
    //decltype(T()+U()) add(T t, U u)                   //          ,             ,        
    //decltype( (*(T*)0) + (*(U*)0) ) add(T t, U u)     //OK,     
    auto add(T t, U u) -> decltype(t+u)
    {
        return (t + u);
    }

    템플릿 별칭
    typedef std::map<:string int=""> map_s_i;
    map_s_i mymap1{std::make_pair("first",1)};
    
    typedef std::map<:string std::string=""> map_s_s;
    map_s_s mymap2{ std::make_pair("second","second") };
    
    //       std::string  map key,           ( int、long、string )
    
    // c++98|C++03,       
    template
    struct mymap
    {
        typedef std::map<:string t=""> type;
    };
    mymap::type mymap3;
    mymap::type mymap3;
    
    //c++11
    template 
    using mymapt = std::map<:string t="">;
    mymapt mymap4;
    
    //         using, c++11 ,  using      typedef
    using funcType = int(*)(int,int);
    
    template
    using funcT = int(*)(T,T);
    
    int func_int(int n1,int n2)
    {
      return n1+n2;
    }
    
    funcT func_i = func_int;
    func_i(1,2);

    함수 템플릿 기본 매개 변수
      c++ 11 이전에는 클래스 템플릿에만 기본 템플릿 매개 변수를 제공할 수 있었고 c++ 11 이후에는 함수 템플릿에 기본 매개 변수를 제공할 수 있습니다
    template
    class myarray
    {
    private:
        T arr[size];
    public:
        void myfunc();
    }
    
    class tc
    {
    public:
        tc() { std::cout << "    " << std::endl; }
        tc(const tc& t) { std::cout << "    " << std::endl; }
        int operator()(int v1, int v2)const
        {
            return v1 + v2;
        }
    };
    
    template
    T test(const T& i, const T& j, F funcpoint = F())
    {
        return funcpoint(i, j);
    }
    
    
    template 
    auto func(U val)->decltype(val)
    {
        std::cout << typeid(val).name() << std::endl;
        return  val;
    }
    
    //        ,          ,            
    func(123);
    // T  <<  std::string  <<  U  <<  123.363
    func<:string>(123.363);

    tuple
  • tuple구조의tuple대상이 저장한 것은 구조실참의 복사
  • make_tuple: 구조tuple 대상이 저장한 것은 구조실삼의 복사
  • tie:tie구조의tuple대상을 통해 구조실삼의 쓰기 가능한 인용을 저장
  • forward_as_tuple:forward를 통해as_tuple 구조의tuple 대상, 구조실삼의 원시 인용을 저장하고 왼쪽 값은 왼쪽 값 인용, 오른쪽 값은 오른쪽 값 인용
  • template
    struct TuplePrinter
    {
        static void print(const Tuple& t)
        {
            TuplePrinter::print(t);
            std::cout << " " << std::get(t);
        }
    };
    
    template
    struct TuplePrinter
    {
        static void print(const Tuple& t)
        {
            std::cout << std::get<0>(t);
        }
    };
    
    template
    void print(const std::tuple& t)
    {
        std::cout << "( ";
        TuplePrinter::print(t);
        std::cout << " )
    "; } void show() { std::cout << std::endl; } template void show(const T& t, const Args &... args) { std::cout << t << " "; show(args...); } int main() { int age = 20; float height = 170.6; std::string name = " "; std::cout << "----- tuple() -----" << std::endl; // tuple std::tuple<:string int="" float=""> tp1(name, age, height); // print(tp1); // std::get<0>(tp1) = " "; std::get<1>(tp1) = 40; std::get<2>(tp1) = 16.8; // print(tp1); // ; ,tuple show("(", name, age, height, ")"); std::cout << "----- make_tuple -----" << std::endl; // make_tuple tuple // auto tp2 = std::make_tuple(name, age, height); auto tp2 = std::make_tuple("hello", 1, 2.0); // // print(tp2); // std::get<0>(tp2) = " "; std::get<1>(tp2) = 35; std::get<2>(tp2) = 18.0; // print(tp2); // ; ,make_tuple show("(", name, age, height, ")"); std::cout << "----- tie -----" << std::endl; // tie tuple auto tp3 = std::tie(name, age, height); // auto tp3 = std::tie("hello", 2, 2); // print(tp3); // std::get<0>(tp3) = " "; std::get<1>(tp3) = 35; std::get<2>(tp3) = 18.0; // print(tp3); // ; , show("(", name, age, height, ")"); std::cout << "----- tie parser tuple-----" << std::endl; // tie tuple auto tp4 = std::make_tuple(" ", 30, 1.85); tie(name, age, height) = tp4; show("(", name, age, height, ")"); std::cout << "----- forward_as_tuple lvalue-----" << std::endl; auto tp5 = forward_as_tuple(name, age, height); // print(tp4); // ,get std::get<0>(tp5) = " "; std::get<1>(tp5) = 35; std::get<2>(tp5) = 18.0; // print(tp4); // ; , show("(", name, age, height, ")"); std::cout << "----- forward_as_tuple rvalue-----" << std::endl; auto tp6 = std::forward_as_tuple(" ", 30, 1.85); // print(tp6); // , get , // std::get<0>(tp6) = " "; // std::get<1>(tp6) = 35; // std::get<2>(tp6) = 18.0; return 0; }

    내용 출처: C++11 코드 최적화 및 엔지니어링 응용 깊이

    좋은 웹페이지 즐겨찾기