パスワードを忘れた? アカウント作成
99478 journal

eldeshの日記: 右辺値参照1/N

日記 by eldesh
右辺値参照勉強中….

とりあえず分かったことを書いてみる.
(新しく分かったことだけ書くのでまとまってない.)

右辺値参照とは
  • せっかく作った一時変数を有効利用(エコ++)
  • 右|左辺値参照は値の性質ではなく,式の性質である.
  • 名前が付いてる式は左辺値参照である
  • 名前が付いてないなら右辺値参照である(ちょっと怪しいかも
  • 左辺値参照とオーバーロードできる
  • 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部終了.

この議論は賞味期限が切れたので、アーカイブ化されています。 新たにコメントを付けることはできません。
typodupeerror

吾輩はリファレンスである。名前はまだ無い -- perlの中の人

読み込み中...