読者です 読者をやめる 読者になる 読者になる

ムラサメ研究ブログ

主にゲームやプログラミングのログ

右辺値参照~完全転送まで100%理解するぞ! part2 VisualStudioの罠

C++ rvalue ref

はじめに

おまけ。 右辺値参照を理解するうえで大きな妨げになった VisualStudioでの挙動(バグ?? 詳細希望)

左辺値は暗黙で右辺値参照にキャスト出来ない

バグ? の前に基礎から 左辺値(参照)は 左辺値にのみ 右辺値(参照)は 右辺値にのみ 暗黙キャストがゆるされる

#include<iostream>

void foo1(int& i) {}
void foo2(int&& i) {}


auto main() -> int{

    int i;
    int &i1(i);                        // lvalue -> lvalue ref         well-formed
    int &i2(i1);                   // lvalue ref -> lvalue ref     well-formed
// int &i3(1);                     // rvalue -> lvalue ref          ill-formed

    int &&ii(1);                  // rvalue -> rvalue ref         well-formed
// int &&ii2(ii);                  // lvalue ref -> rvalue ref      ill-formed    iiは右辺値を代入しているがそれ自体は左辺値(アドレスが存在する)
    int &&ii3(std::move(ii));      // rvalue ref -> rvalue ref     well-formed


    foo1(i);                        // lvalue -> lvalue ref         well-formed
    foo1(i1);                       // lvalue ref -> lvalue ref     well-formed
// foo1(1);                        // rvalue -> lvalue ref          ill-formed

    foo2(1);                       // rvalue -> rvalue ref         well-formed
// foo2(ii);                       // lvalue ref -> rvalue ref      ill-formed    iiは右辺値を代入しているがそれ自体は左辺値(アドレスが存在する)
    foo2(std::move(ii));            // rvalue ref -> rvalue ref     well-formed
}

上記の通り、右辺値参照と左辺値参照は 暗黙で変換できないので std::moveでキャストする必要がある

VCの不具合??

stringやvector等で試すと不思議なことがおこった

#include<iostream>

void Str(std::string& s) {
}

auto main() -> int{
  Str( std::string("right value"));  // rvalue -> lvalue ref   ill-formだがVisualStudioでは通る・・
}

clanやgccで試したが 当然エラーになるし VisualStudioでも int等で試すとエラーになるが stringやvector等のコンテナだと いずれも上記のコードが通るので 移植性を考える場合は 上記のコードを書かないようにすべきと思われる