2016-12-23 13 views
5

なぜ曖昧さがないのですか?ここでオーバーロード解決時にconst左辺参照がconst rvalue参照よりも優先される理由

struct B {}; 
struct C {}; 

struct A 
{ 
    A(B const &, C const &) {} 
    A(B const &&, C const &&) = delete; 
#if 0 
    A(B const &, C const &&) = delete; 
    A(B const &&, C const &) = delete; 
#endif 
}; 

B const b() { return {}; } // const result type may make sense 
C const c() { return {}; } // for some user-defined types 

int main() 
{ 
    A a0{B{}, C{}}; // I want to prohibit this 
    A a1{b(), c()}; // and this cases 
    B const bb{}; 
    C const cc{}; 
    A a2{b(), cc}; // But surely I also want to prohibit this 
    A a3{bb, c()}; // and this cases to compile 
} 

私はAのインスタンスにBCインスタンスへの左辺値のconst参照を格納します。もちろん、参照されたオブジェクトの存続期間がAのインスタンスの生存期間を克服することを確実にしたいと思います。加えて、対応B &&C &&にマッチしB const &&C const &&ため、この私だけ= delete;オーバーロードを達成するために

上記のアプローチは、変換コンストラクタ(つまり単項式)に対して完全に機能します。しかし、より高いアライテンスについては、関心のあるパラメータ(すなわち、#if 1)の定数の基準バージョンを取り囲む、組み合わせ可能なすべての組み合わせを明示的に= delete;する必要があることが分かります。

私は、「あいまいさがないのはなぜですか?」と思っています。なぜなら、あいまいさは、上記の場合に間違ったコードのコンパイルを防ぐべきだからです。

"なぜコンストラクタの呼び出しが混在している場合にあいまいさがないのですか?"

+0

'B const &&'は左辺値にバインドされません。そのコンストラクタは 'a3'のためには実行可能ではありません。同様に 'a2'。 –

+0

@ T.C。 'B const&'は任意の種類のrvalueにバインドします。 – Orient

+2

はい、逆ではありません。それは全体のポイントです。 –

答えて

5

tl; dr:それは - そのように設計されました。

the original move proposalよりコードがあいまいです。その提案の下では、左辺値は右辺値参照にバインドするになりますが、左辺値セットが存在する場合は左辺値参照が優先されます。

プロセスのかなり後半で、より多くの人々が提案を理解し始め、概念がまだC++ 11のために考慮されていたので、the rules were changed so that lvalues could not bind to rvalue references

私は個人的にはこの変更が必要だとは思わなかったが、遠くに多くの人が変更を気に入っていないと思っていましたが、移動セマンティクスの基本機能はいずれにしてもうまくいきました。だから、これは絶対に移動セマンティクスを得られないのとは対照的に、価値のある妥協点でした。

左辺値が右辺値参照にバインドできないという変更では、のいずれかの値が左辺値の場合は、A(B const &&, C const &&)は過負荷解決の一部になりません。ただし、いずれか(または両方)の引数が左辺値の場合、A(B const &, C const &)はオーバーロードセットのままです。

+0

'const &&'が 'const&'と同じ値のカテゴリをすべてバインドできたら、問題はなくなります。確かに、対応するカテゴリのマッチングが優先されるべきです。 – Orient

+0

@オリエント:あなたは正しいです。これが元の移動提案です。 2009年にN2812がそれを変更しました。今はこの変更を元に戻すことは現実的ではないと思います。 –

+0

'const &&'はめったに使われません( 'auto'キーワードのように90 'と10'の間)。だから、 'const &&'の意味は変えられるが、 '&&'の意味が保持されると、何も間違っていないのだろうか?ちょうど架空のケース。 – Orient

関連する問題