N2844 - Fixing a Safety Problem with Rvalue References の翻訳
翻訳してみました。
要約っぽいの
右辺値参照は「型安全オーバーロードの原則」に反しているという話。
template<typename T> class list { public: void push_back(const value_type& x); // #1 void push_back(value_type&& x); // #2 };
void do_push_back(std::list<std::unique_ptr<int>> &l, std::unique_ptr<int> x) { l.push_back(x); }
と書いたとき、#1 の push_back が選択されて失敗して期待通りになるんだけど、
requires CopyConstructible<value_type> void push_back(const value_type& x); // #1 requires MoveConstructible<value_type> void push_back(value_type&& x); // #2
こうやって書くと、今の仕様だと右辺値参照は左辺値を束縛できるので、#2 のオーバーロードが選択されて左辺値からリソースが移動してしまう。
これは右辺値参照が、オーバーロード解決の順番によって結果が変わってしまうので、型安全オーバーロードの原則に反している。
なので右辺値参照が左辺値を束縛できないように変更する。
ただし左辺値から、テンポラリを作らない右辺値参照へ static_cast をするのは問題ないそうな。
int i = 2; double&& rd = i; // 以前は OK だったけど、今はダメ int&& n = i; // 以前は OK だったけど、今はダメ int&& n = static_cast<int&&>(i); // これは OK
ということかな?