右辺値参照が分からない

「一時オブジェクトを渡したときに移動できるようにするのね」と理解したつもりでコードを書いてみたけど、よく分からないところが…

#include <string>

using namespace std;

class Foo {
  string s;
public:
  Foo(const char* cs) {
    cout << "constructor" << endl;
  }

  Foo(const Foo& foo) {
    cout << "copy constructor" << endl;
  }

  Foo(Foo&& foo) {
    cout << "move constructor" << endl;
  }
};

void bar(Foo& foo) {
  cout << "copy bar" << endl;
}

void bar(Foo&& foo) {
  cout << "move bar" << endl;
}

void hl() {
  cout << "-----" << endl;
}

int main() {
  Foo foo1("test");          // constructorが呼ばれる
  hl();
  Foo foo2(foo1);            // copy constructorが呼ばれる
  hl();
  Foo foo3_1(Foo("test"));   // move constructorが…呼ばれない?
  hl();
  Foo foo3_2 = Foo("test");  // これもだめ
  hl();
  Foo foo3_3 = std::move(Foo("test"));  // move constructorが呼ばれた…

  hl();
  bar(foo1);         // copy barが呼ばれる
  hl();
  bar(Foo("test"));  // move barが…呼ばれた。なんで?
  hl();
  bar(std::move(Foo("test")));  // move barが呼ばれた

  return 0;
}

「Foo foo3_1(Foo("test"));」でmove constructorが呼ばれと思ったら、呼ばれない。std::moveでくくったらmove constructorが呼ばれるようになったけど、「bar(Foo("test"));」との差がよく分からない。VC固有の動作かと思ったら、g++でも同じように動いた。

まだ名前を付けてないのに、なんで左辺値として扱われているんだろう?


追記
理由を少し考えてみた。

Foo foo3_1(Foo("test"));

上の例だと分かりにくいけど、下の場合

Foo foo3_2 = Foo("test");
// Foo foo3_2("test")と同じじゃね?

ふっつーにオブジェクトを作っているものと解釈されて、move constructorが呼ばれないんじゃないかなぁ、と推測。

つまり下の3つの書き方は全部同じ意味ですよ、と。

Foo foo("xxx");
Foo foo = Foo("xxx");
Foo foo(Foo("xxx"));

右と左で同じオブジェクト作って、即移動なんてないだろうから、当たり前のような気がする。
仕様書読むかなぁ。。。