C++/Library 2021. 3. 30. 00:06

forward

  • <utility> 라이브러리

예제

간단

  • forward를 사용하지 않았을 경우

    #include <iostream>
    
    struct MyStruct
    {};
    
    void    func(MyStruct& s)
    {
        std::cout << "Pass by L-ref\n";
    }
    
    void    func(MyStruct&& s)
    {
        std::cout << "Pass by R-ref\n";
    }
    
    template <typename T>
    void    func_wrapper(T t)
    {
        func(t);
    }
    
    int        main()
    {
        using namespace std;
    
        MyStruct s;
    
        func_wrapper(s);
        func_wrapper(MyStruct());
    }
    
    /* stdout
    Pass by L-ref
    Pass by L-ref
    */
  • func_wrapper의 파라미터를 T &&으로 받아도 결과는 같다.

    • 파라미터를 R-value로 받더라도 t 자체가 변수이기 때문에 L-value로 인식하는 것 같다.
    #include <iostream>
    
    struct MyStruct
    {};
    
    void    func(MyStruct& s)
    {
        std::cout << "Pass by L-ref\n";
    }
    
    void    func(MyStruct&& s)
    {
        std::cout << "Pass by R-ref\n";
    }
    
    template <typename T>
    void    func_wrapper(T&& t)
    {
        func(t);
    }
    
    int        main()
    {
        using namespace std;
    
        MyStruct s;
    
        func_wrapper(s);
        func_wrapper(MyStruct());
    }
    
    /* stdout
    Pass by L-ref
    Pass by L-ref
    */
  • R-ref를 제대로 전달하고 싶으면, 다음과 같이 forward를 사용하면 된다.

    #include <iostream>
    #include <vector>
    #include <utility>
    
    struct MyStruct
    {};
    
    void    func(MyStruct& s)
    {
        std::cout << "Pass by L-ref\n";
    }
    
    void    func(MyStruct&& s)
    {
        std::cout << "Pass by R-ref\n";
    }
    
    template <typename T>
    void    func_wrapper(T&& t)
    {
        func(std::forward<T>(t));
    }
    
    int        main()
    {
        using namespace std;
    
        MyStruct s;
    
        func_wrapper(s);
        func_wrapper(MyStruct());
    }
    
    /* stdout
    Pass by L-ref
    Pass by R-ref
    */

컨테이너 예제

  • std::move의 경우 명확한 의도를 보여주기 위해서 사용하기도 한다.

    #include <iostream>
    #include <utility>
    
    class CustomVector
    {
        unsigned    n_data_ = 0;
        int*        ptr_ = nullptr;
    
    public:
        CustomVector(const unsigned& n_data, const int& init_in = 0)
        {
            std::cout << "Constructor\n";
            init(n_data, init_in);
        }
    
        CustomVector(CustomVector& l_input)
        {
            std::cout << "Copy Constructor\n";
    
            init(l_input.n_data_);
    
            for (unsigned i = 0; i < n_data_; ++i)
                ptr_[i] = l_input.ptr_[i];
        }
    
        CustomVector(CustomVector&& r_input)
        {
            std::cout << "Move Constructor\n";
    
            n_data_ = r_input.n_data_;
            ptr_ = r_input.ptr_;
    
            r_input.n_data_ = 0;
            r_input.ptr_ = nullptr;
        }
    
        ~CustomVector()
        {
            delete[] ptr_;
        }
    
        void    init(const unsigned& n_data, const int& init_in = 0)
        {
            n_data_ = n_data;
            ptr_ = new int[n_data_];
            for (unsigned i = 0; i < n_data_; ++i)
                ptr_[i] = init_in;
        }
    };
    
    void    doSomething(CustomVector& vec)
    {
        std::cout << "Pass by L-reference\n";
        CustomVector new_vec(vec);
    }
    
    void    doSomething(CustomVector&& vec)
    {
        std::cout << "Pass by R-reference\n";
        CustomVector new_vec(std::move(vec));  // 명확한 의도를 보여주기 위해 move 사용
        //CustomVector new_vec(vec);
    }
    
    template <typename T>
    void    doSomethingTemplate(T&& vec)
    {
        doSomething(std::forward<T>(vec));
    }
    
    int        main()
    {
        using namespace std;
    
        CustomVector    my_vec(10, 1024);
    
        doSomethingTemplate(my_vec);
        doSomethingTemplate(CustomVector(10, 123));
    }
    
    /* stdout
    Constructor
    Pass by L-reference
    Copy Constructor
    Constructor
    Pass by R-reference
    Move Constructor
    */

'C++ > Library' 카테고리의 다른 글

C++ future  (0) 2021.03.30
C++ 멀티쓰레딩 (Multithreading)  (0) 2021.03.30
C++ atomic  (0) 2021.03.30
C++ mutex  (0) 2021.03.30
C++ 파일 임의 위치 접근  (0) 2021.03.29