まず、最初の 2 つの場合、左辺値変換 (左辺値から右辺値への変換) があることを除いて、3 つすべての変換シーケンスは同じですが、変換シーケンスの順序付けには使用されません。3 つすべてが完全に一致します (関数テンプレートの特殊化にはパラメーター type がありますchar const(&)[2]
)。
でルールを反復すると、13.3.3.2p3
この段落で停止します
S1 と S2 は参照バインディング (8.5.3) であり、どちらも参照修飾子なしで宣言された非静的メンバー関数の暗黙的なオブジェクト パラメーターを参照せず、S1 は右辺値参照を右辺値にバインドし、S2 は左辺値参照をバインドします。
左辺値への右辺値参照のバインドが必要な場合、変換シーケンスを形成することはできません。仕様は 13.3.3.1.4p3 で述べています。8.5.3p5 の最後の箇条書きで参照バインディングがどのように機能するかを見ると、配列の左辺値から型の一時 (rvalue 一時を意味していると思います)が作成され、その一時への参照がバインドされます。したがって、よりも優れているchar const*
と思います。againstについても同じことが言えますが、 はテンプレートであるため必要ありませんが、同点の場合は再度選択します。(1)
(2)
(1)
(3)
(3)
(1)
ではn3225
、参照バインディング ルールを変更して、参照が右辺値にバインドされる限り、右辺値参照が左辺値であるイニシャライザ式にバインドできるようにしました (おそらく、以前に初期化子を適切に変換することによって作成されました)。これは、ここでは最新ではない可能性がある Visual C++ による処理に影響を与える可能性があります。
クランについてはよくわかりません。を無視(1)
したとしても、 と の間で引き分けに(2)
なり、非テンプレートであるため(3)
選択する必要があります。(2)
8.5.3p5 の最後の箇条書きは「それ以外の場合は型の一時的な..」と書いてあるので紛らわしいと思います。13.3.3.1.4p3 で一時的な値が左辺値または右辺値と見なされるかどうかは明確ではありません。つまり、仕様の正確な言葉に従って、以下が実際にどのように動作するかわかりません。
void f(int &);
void f(int &&);
int main() {
int n = 0;
f(n);
}
13 節でテンポラリが右辺値として扱われると仮定すると、右辺値参照を 2 番目の関数で右辺値にバインドし、最初の関数で左辺値にバインドします。したがって、2 番目の関数を選択し、最後の箇条書き 8.5.3p5 までに診断を取得しT1
ますT2
。13 節でテンポラリが左辺値として扱われると仮定すると、以下は機能しません。
void f(int &&);
int main() {
f(0);
}
右辺値参照を左辺値にバインドすると、節 13 によって関数が実行不可能になるためです。また、「右辺値参照を左辺値にバインドする」を、バインドされた最終的な式ではなく、初期化子式を参照するものとして解釈すると、次は受け入れられません。
void f(float &&);
int main() {
int n = 0;
f(n);
}
ただし、これは n3225 の時点で有効です。そのため、混乱が生じているようです。私はこれについて委員会に DR を送りました。