【初心者向け】C++におけるlvalue、rvalue、xvalue、glvalue、prvalueをわかりやすく解説
C++における値のカテゴリ:lvalue、rvalue、xvalue、glvalue、prvalue
lvalue(左辺値)
lvalueは、"left-value"の略で、プログラムが値を取得したり書き換えたりできる式を表します。具体的には、以下の要素がlvalueに該当します。
- 変数名
- 配列要素
- 構造体・共用体のメンバ変数
- 関数呼び出し(lvalue参照を返す場合)
- アドレス演算子(&)で取得したポインタ
lvalueの例:
int x = 10; // 変数名
int arr[] = {1, 2, 3}; // 配列要素
struct Point {
int x, y;
} p; // 構造体メンバ変数
int func() &; // lvalue参照を返す関数
int* ptr = &x; // アドレス演算子で取得したポインタ
rvalueは、"right-value"の略で、lvalueとは異なり、プログラムが値を取得することしかできない式を表します。具体的には、以下の要素がrvalueに該当します。
- リテラル(整数、文字列、浮動小数点など)
- 演算式
- 対象を持たない一時オブジェクト
10; // 整数リテラル
"Hello, world!" // 文字列リテラル
3.14159; // 浮動小数点リテラル
func(); // lvalue参照を返さない関数
x + y; // 演算式
xvalue(移動可能なrvalue)
xvalueは、"movable rvalue"の略で、移動演算子を用いて所有権を移動できるrvalueを表します。具体的には、以下の要素がxvalueに該当します。
- rvalue参照を返す関数呼び出し
- rvalue参照型へのキャスト
std::move(x); // rvalue参照を返す関数呼び出し
static_cast<std::move_iterator<int*>>(ptr); // rvalue参照型へのキャスト
glvalueは、**"generalized left-value"**の略で、lvalueとxvalueを包括する概念です。つまり、glvalue式は、プログラムが値を取得したり書き換えたり、所有権を移動したりすることができます。
glvalue = lvalue ∪ xvalue
prvalueは、**"pure rvalue"**の略で、xvalueではないrvalueを表します。具体的には、以下の要素がprvalueに該当します。
- リテラル
lvalue、rvalue、xvalue、glvalue、prvalueは、C++における式の値を表現するための重要な概念です。これらの概念を理解することで、C++プログラムの動作をより深く理解することができます。
- C++11では、rvalue参照が導入され、xvalueの概念が追加されました。
- rvalue参照とxvalueは、移動セマンティクスと呼ばれる機能と密接に関連しています。移動セマンティクスは、リソースのコピーではなく所有権の移動を行うことで、パフォーマンスを向上させることができます。
int x = 10; // 変数 (lvalue)
// xの値を取得
int y = x;
// xの値を書き換える
x = 20;
int y = 10; // リテラル (rvalue)
// yの値を取得 (コピー)
int z = y;
// yの値を書き換えることはできない
y = 20; // エラー
std::vector<int> vec = {1, 2, 3}; // コンテナ (lvalue)
// vecの要素をxvalueとして取得
auto it = vec.begin();
int value = *it;
// vecの要素を書き換えることはできない
*it = 10; // エラー
// vecの所有権を移動
std::vector<int> new_vec = std::move(vec);
glvalueとprvalueの例
int x = 10; // 変数 (glvalue)
int y = 10; // リテラル (prvalue)
// xとyを比較
if (x == y) {
// ...
}
図表による説明
値のカテゴリの関係を図表で表すことで、理解しやすくなります。以下は、lvalue、rvalue、xvalueの関係を示す図表の一例です。
式
/\
/ \
lvalue rvalue
/\
/ \
glvalue prvalue
/\
/ \
xvalue ...
類似概念との比較
lvalue、rvalue、xvalueなどの概念は、他のプログラミング言語における類似概念と比較することで理解しやすくなります。例えば、以下のように比較することができます。
C++ | Java | C# |
---|---|---|
lvalue | 左辺値 | 左辺値 |
rvalue | 右辺値 | 右辺値 |
xvalue | 移動可能なrvalue | 移動可能なrvalue |
glvalue | 一般化左辺値 | 一般化左辺値 |
prvalue | 純粋な右辺値 | 純粋な右辺値 |
実践的な例
これらのリソースは、lvalue、rvalue、xvalueなどの概念をより深く理解し、実際のコードでどのように使用するのかを学ぶのに役立ちます。
c++ c++11 expression