「右辺値参照を取る関数は、右辺値参照 (名前のない一時変数) と左辺値参照 (名前付きの非定数参照) の両方を取ることができるため」
これは間違った記述です。右辺値参照仕様の最初の繰り返しではこれは真実でしたが、もはやそうではなく、少なくともこの後の変更に準拠するために MSVC に実装されています。つまり、これは違法です。
void f(char&&);
char x;
f(x);
左辺値で右辺値参照を期待する関数を呼び出すには、次のように右辺値に変換する必要があります。
f(std::move(x))
もちろん、その構文は、左辺値参照を受け取る関数と右辺値参照を受け取る関数の実際の違いを明確に示しています。右辺値参照は、呼び出しに耐えることが期待されていません。これは大したことです。
もちろん、std::move が行うこととまったく同じことを行う新しい関数を作成して、右辺値参照のような右辺値参照を使用することができます。たとえば、私が持っているビジター フレームワークでこれを行うことを考えました。ビジター呼び出しの結果を単に気にしない場合もありますが、そうでない場合もあるため、その場合は左辺値参照が必要です。右辺値参照を使用すると、両方を取得できます...しかし、右辺値参照のセマンティクスに違反しているため、それは悪い考えだと判断しました。
あなたの声明は、これに基づいて混乱している可能性があります。
template < typename T >
void f(T&&);
char x;
f(x);
これは機能しますが、左辺値を右辺値参照として渡しているためではありません。これは、参照減衰のために機能します (これも C++0x の新機能です)。そのようなテンプレートに左辺値を渡すと、実際には次のようにインスタンス化されます。
void f<char&>(char&&&);
参照の減衰は、実際のインスタンス化は次のように&&&
なり&
ます。
void f<char&>(char&);
言い換えれば、参照によって左辺値を渡すだけです...それについて新しいことや特別なことは何もありません。
問題が解決することを願っています。