左と右の話
- 4. i
int &f(); f() 全て規格に
4
左辺値・右辺値とは
全ての式がおのおの持つ属性
左辺値となる式
右辺値となる式
42, i + j
int g(); g()
MyClass(arg)
書いてある
- 17. “j” という式の値を格納した場所
(左辺値)に, “i” という式の値
(右辺値)を代入する
左辺値から
右辺値への変換
lvalue-to-rvalue
17
代入演算子は
右辺に右辺値が欲しい!
j = i
j = i
conversion
- 20. 20
式の左辺値・右辺値に関する
2つの視点とL-to-R 変換
ある式が左辺値
である
右辺値
である
出現して
いる文脈
で
左辺値である
ことが要求さ
れている
そのま
まで
O.K.
コンパ
イルエ
ラー
右辺値である
ことが要求さ
れている
L-to-R
変換が
起きる
そのま
まで
O.K.
- 21. 21
式の左辺値・右辺値に関する
2つの視点とL-to-R 変換
ある式が左辺値
である
右辺値
である
出現して
いる文脈
で
左辺値である
ことが要求さ
れている
そのま
まで
O.K.
コンパ
イルエ
ラー
右辺値である
ことが要求さ
れている
L-to-R
変換が
起きる
そのま
まで
O.K.
&42
42=0
- 22. 22
全ては規格のシナリオ通りに
• 式自身が左辺値か右辺値か
⇒全て規格に書いてある
• 個々の文脈で式に左辺値・
右辺値のどちらが要求されるか
⇒全て規格に書いてある
• いつ左辺値から右辺値への
変換が起きるか
⇒全て上2つから判断できる
- 26. 例:オブジェクトが未構築な
領域にどんな操作が許されるか?
26
オブジェクトに対して左辺値から
右辺値への変換が起きたらアウト
void *p = std::malloc(sizeof(int
int &ri = *p;
セーフ
&ri;
ri + 1;
アウト
int *pi = new (p) int(42);
- 28. 28
例:型の完全な定義が
いつ必要になるか?
左辺値から右辺値への変換が起きた
オブジェクトの型は完全でなければならない
class X;
void f(X &x) {
セーフ
&x;
static_cast<X>(x);
} アウト
- 29. 29
例:変数の定義がいつ必要に
なる(odr-usedされる)か?
変数がコード中に出現すればodr-used
ただし,変数がconstant expression であり
即座にL-to-R 変換が起きる場合は対象外
Template<typename T>
struct X {
static constexpr int i = 42;
};
int j = i + 1;
int *p = &i;
アウト
セーフ
- 32. xvalue, prvalue,
glvalue の話はどこに行った?
“Location” の
意味を持つか
寿命が短い
lvaue Yes No
xvalue Yes Yes
prvalue No Yes
今日の発表の
左と右の境界
- 33. xvalue, prvalue,
glvalue の話はどこに行った?
“Location” の
意味を持つか
寿命が短い
lvaue Yes No
xvalue Yes Yes
prvalue No Yes
move semantics, 右辺値参照で
重要な左と右の境界
- 34. まとめ:
• 左辺値とは何か,右辺値とは何か
• 左辺値から右辺値への変換とは何か,それは
いつ起きるのか
• 左辺値から右辺値への変換がいつ起きるのか
は様々なコーナーケースでの判断に重要
• 左辺値と右辺値の区別はmove semantics,
右辺値参照の話でも重要だが,本発表での左
辺値と右辺値の区別の場合と境界線が異なる
34