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

ということかな?