C++11新特性:std::move()和std::forward()

    C++11經過std::move()和std::forward()函數分別實現了左值轉右值和完美轉發的功能。app

    對於std::move(),考慮以下情形:函數

    void func(int &&args) {spa

        std::cout << args << std::endl;原型

    }引用

    int a = 10;error

    func(20);    // okco

    func(a);      // error, 右值引用不能綁定左值background

    func(std::move(a));    // okreturn

    

    對於std::forward(),完美轉發,當參數

    void func(int &arg) {
        std::cout << "func lvalue" << std::endl;
    }

    void func(int &&arg) {
        std::cout << "func rvalue" << std::endl;
    }

    template <typename T>
    void wrapper(T &&args) {
        func(args);
    }

    int main() {
        int a = 10; 

        wrapper(a);
        wrapper(20);

        return 0;
    }
    以上函數輸出:

        func lvalue
        func lvalue

    雖然咱們調用wrapper()函數時,傳入的參數一個是左值,一個是右值,可是最終的輸出確都是左值。緣由是咱們在中間加了一層轉發函數wrapper()。

    引用疊加,引用是能夠疊加的,對於 T &&a; 疊加規則以下:

    (1)當T類型爲 Type 時,a 爲 Type &&a,右值引用。

    (2)當T類型爲 Type& 時,a爲 Type &a,左值引用。

    (3)當T類型爲 Type&& 時,a爲 Type &&a,右值引用。

   經過引用疊加,分析以上示例可知,調用wrapper()時,wrapper(a) 是調用的原型是 wrapper(int &),是左值調用;wrapper(20)調用的原型是wrapper(int &&),是右值調用。可是在wrapper()函數內部,不管如何,args都是一個左值,在調用func()函數的時候,調用的func()原型老是func(int &)。

    所以,根本緣由實際上是,右值引用屬性不能被轉發。因此,C++11提供了std::forward()函數用於完美轉發。即,在轉發過程當中,左值引用在被轉發以後仍然保持左值屬性,右值引用在被轉發以後依然保持右值屬性。修改以後的代碼以下:

 void func(int &arg) {
        std::cout << "func lvalue" << std::endl;
    }

    void func(int &&arg) {
        std::cout << "func rvalue" << std::endl;
    }

    template <typename T>
    void wrapper(T &&args) {
        func(std::forward<T>(args));
    }

    int main() {
        int a = 10; 

        wrapper(a);
        wrapper(20);

        return 0;
    }

    如此,輸出以下:

        func lvalue         func rvalue

相關文章
相關標籤/搜索