私がC++ 11のリファレンスを理解する限り、左辺は一時的にバインドされていて、左辺は絶対値にバインドされてはならないため、左辺の参照は(非const)左辺参照にバインドできません。一時的。私はライン(X)
でs << Dummy()
を記述する場合、C++はなぜ私はstd :: stream rvalue refをlvalue refに移動できますか?
(A)
に文句(私は限り私ができるように減少)連動の一時ストリームオブジェクト
struct Dummy {};
template <typename Stream>
Stream& operator<<(Stream& s, Dummy) {
return s << "."; // <- (A)
}
template <typename Stream>
void pass(Stream&& s) {
std::move(s) << Dummy(); // <- (X) rvalue->lvalue conversion?
}
#include <fstream>
int main() {
pass(std::fstream("test",std::ios::out));
}
にこの奇妙な振る舞いを見つけしかし
error: invalid initialization of reference of type ‘std::basic_fstream<char>&’ from expression of type ‘std::basic_ostream<char>’
しかし、なぜコードは上記のようにをコンパイルし、期待通りに動作します? std::move
によって返されたrvalue参照は、式s
のように左辺値の参照にバインドできないようにする必要がありますが、gcc 4.6.1
とgcc 4.7.2
の両方が同じように反応します。
なぜこの現象はストリームでしか機能しないように見えますか? T&
を期待する関数にDummy&&
を直接渡すと、std::move
の有無にかかわらず失敗します。
です。それは意味をなさない。しかし、なぜ 'std :: move'が必要なのですか? – bitmask
@bitmask:それがないと 's'は左辺値であるので、右辺値参照にバインドできません。 –
@KerrekSB:しかし、(この答えに示されているように)右値参照ストリームがバインドするための完全なオーバーロードがあります。 'std :: move'の励まされることなく、そのオーバーロードがマッチしないのはなぜですか? – bitmask