logo MSJO.kr

C++, RValue Reference and Move

2020-12-08
MsJ

Rvalue reference는 C++11에서 처음 소개된 기능으로 다소 이해하기 어려운 구조1로 되어있다. Each C++ expression (an operator with its operands, a literal, a variable name, etc.) is characterized by two independent properties: a type and a value category. Each expression has some non-reference type, and each expression belongs to exactly one of the three primary value categories: prvalue, xvalue, and lvalue2.

  • a glvalue (“generalized” lvalue) is an expression whose evaluation determines the identity of an object, bit-field, or function;
  • an xvalue (an “eXpiring” value) is a glvalue that denotes an object or bit-field whose resources can be reused;
  • n lvalue (so-called, historically, because lvalues could appear on the left-hand side of an assignment expression) is a glvalue that is not an xvalue;
  • an rvalue (so-called, historically, because rvalues could appear on the right-hand side of an assignment expression) is a prvalue or an xvalue.

C++의 RValue 참조 및 Move 생성자 개념을 간단한 예제3를 통하여 정리해보았다.

RValue 기본 예제
#include <iostream>

using namespace std;

void SomeFun(int &ref)
{
    cout << "SomeFun Normal: " << ref << endl;
}

void SomeFun(int &&ref)
{
    cout << "SomeFun RValue: " << ref << endl;
}

int main()
{
    int a = 1;
    SomeFun(a); // Normal(1)

    SomeFun(2); // RValue(2)

    return 0;
}
#include <iostream>
#include <string>
#include <vector>

using namespace std;

void storeByValue(string s)
{
    string b = s;
    cout << &b << " (1): " << b << endl;
}

void storeByLRef(string &s)
{
    string b = s;
    cout << &b << " (2): " << b << endl;
}

void storeByRRef(string &&s)
{
    string b = s;
    cout << &b << " (3): " << b << endl;
}

int main()
{
    string a = "abc";
    storeByValue(a);
    storeByLRef(a);
    storeByRRef(move(a));

    return 0;
}
RValue Reference and Move
#include <iostream>
#include <vector>

using namespace std;

struct StructA
{
    int *ptr;

    StructA()
    {
        ptr = new int;
        cout << "StructA() : " << ptr << endl;
    }

    StructA(const StructA &a1)
    {
        this->ptr = new int;
        *this->ptr = *a1.ptr;
        cout << "StructA() Copy : " << ptr << endl;
    }

    StructA(StructA &&a1)
    {
        this->ptr = a1.ptr;
        cout << "StructA() Move : " << ptr << endl;
        a1.ptr = nullptr;
    }

    ~StructA()
    {
        delete ptr;
        cout << "Delete : " << ptr << endl;
    }
};

int main()
{
    /* vector 원형
        std::vector<T,Allocator>::push_back
        void push_back(const T& value);
        void push_back(T&& value); // C++11
    */

    // vector<StructA> v1;
    // v1.push_back(StructA());

    // vector<StructA> v2;
    // StructA a1;
    // v2.push_back(a1);

    vector<StructA> v3;
    StructA a1;
    v3.push_back(move(a1));

    return 0;
}

국내 유튜브 강좌에서 위의 내용을 쉽게 설명한 것은 ‘코드없는 프로그래밍’이 강의한 C++ L-value R-value 강의 강좌 프로그래밍 5강 STL, L VALUE R VALUE 레퍼런스 알아보기에서 볼 수 있다.

Reference
  1. dydtjr1128’s Blog, “What is lvalue, rvalue, xvalue, prvalue, glvalue”
  2. cppreference.com, “Value categories”
  3. CodesBay, “RValue Reference and Move Constructor in C++”

Prεv(Θld)   Nεxt(Nεw)
Content
Search     RSS Feed     BY-NC-ND