eldeshの日記: 右辺値参照1/N
とりあえず分かったことを書いてみる.
(新しく分かったことだけ書くのでまとまってない.)
右辺値参照とは
- せっかく作った一時変数を有効利用(エコ++)
- 右|左辺値参照は値の性質ではなく,式の性質である.
- 名前が付いてる式は左辺値参照である
- 名前が付いてないなら右辺値参照である(ちょっと怪しいかも
- 左辺値参照とオーバーロードできる
- reference collapsionの振る舞いがややこしい(単なる主観)
とりあえず,(03でも使える)左辺値参照とオーバーロードして振り分けてみる.
void print(string const && str){
cout << "Rref:" << str << endl;
}
void print(string const & str){
cout << "Lref:" << str << endl;
}
string str("hoge"); // 左辺値
const string cstr("foo"); // constな左辺値
print(str); // Lref
print(cstr); // Lref
普通に受け取れる.
次は真打登場.
string bar(void){
return "bar";
}
string const bazz(void){
return "bazz";
}
print(bar()); // Rref
print(bazz()); // Rref
print()には,bar()とbazz()の返り値が入ってくるが,
処理系が作った一時変数(名無し)が入ってくるので,
右辺値参照として扱われる.
オーバーロードの規則
オーバーロードはまず,{左|右}で振り分けられてから, {const|か否か}で振り分けられる.
hoge( string const & str ){
cout << "const ref" << endl;
}
hoge( string && str ){
cout << "rvalue ref" << endl;
}
hoge(str); // const ref
hoge(cstr); // const ref
hoge(bar()); // rvalue ref
hoge(bazz()); // rvalue ref
reference collapsion
テンプレートパラメータの置き換えなどで,参照の参照(という型)が出来てしまった場合, ''&''を見なかったことにする規則. 左辺値参照(というか03)にもあるが最近知った.
template< typename T >
void print( T& t ){
}
string str("hoge");
string & p = str;
print<string&>(p); // valid
上の例では,printのパラメータ型がstring&なので, 単純に置き換えるとprintの引数型がT& &となってしまうが, reference collapsionが適用されるのでT& & -> T&として置き換えられる. 変換規則は以下.
ref_collapsing T | T& & = T&
| T&& & = T&
| T& && = T&
| T&& && = T&&
第1部終了.
右辺値参照1/N More ログイン