Resolução de sobrecarga entre object, referência de valor, referência const

Dadas todas as três funções, essa chamada é ambígua.

int f( int ); int f( int && ); int f( int const & ); int q = f( 3 ); 

Remover f( int ) faz com que tanto o Clang quanto o GCC prefiram a referência rvalue sobre a referência lvalue. Mas, em vez disso, remover qualquer sobrecarga de referência resulta em ambiguidade com f( int ) .

A resolução de sobrecarga é geralmente feita em termos de uma ordenação parcial estrita, mas int parece ser equivalente a duas coisas que não são equivalentes entre si. Quais são as regras aqui? Parece que me lembro de um relatório de defeitos sobre isso.

Existe alguma chance int && pode ser preferida sobre int em um padrão futuro? A referência deve se ligar a um inicializador, enquanto o tipo de object não é tão restrito. Portanto, a sobrecarga entre T e T && poderia efetivamente significar “usar o object existente se eu tiver recebido a propriedade, caso contrário, faça uma cópia”. (Isso é semelhante a pura passagem por valor, mas salva a sobrecarga de movimentação.) Como esses compiladores atualmente funcionam, isso deve ser feito sobrecarregando T const & e T && e explicitamente copiando. Mas nem tenho certeza se é estritamente padrão.

Quais são as regras aqui?

Como há apenas um parâmetro, a regra é que uma das três inicializações de parâmetro viáveis ​​desse parâmetro deve corresponder melhor a ambas as outras duas. Quando duas inicializações são comparadas, uma é melhor que a outra, ou nenhuma é melhor (elas são indistinguíveis).

Sem regras especiais sobre binding de referência direta, todas as três inicializações mencionadas seriam indistinguíveis (em todas as três comparações).

As regras especiais sobre vinculação de referência direta tornam int&& melhor que const int& , mas nenhuma é melhor ou pior que int . Portanto, não há melhor correspondência:

 S1 S2 int int&& indistinguishable int const int& indistinguishable int&& const int& S1 better 

int&& é melhor que const int& por causa de 13.3.3.2:

S1 e S2 são ligações de referência (8.5.3) e nenhuma se refere a um parâmetro de object implícito de uma function de membro não estático declarada sem um ref-qualifier, e S1 liga uma referência de valor a um rvalue e S2 liga uma referência de lvalue.

Mas esta regra não se aplica quando uma das inicializações não é uma binding de referência.

Existe alguma chance int && pode ser preferida sobre int em um padrão futuro? A referência deve se ligar a um inicializador, enquanto o tipo de object não é tão restrito. Portanto, a sobrecarga entre T e T && poderia efetivamente significar “usar o object existente se eu tiver recebido a propriedade, caso contrário, faça uma cópia”.

Você propõe tornar uma referência de binding uma correspondência melhor que uma binding sem referência. Por que não publicar sua ideia para propostas futuras do isocpp ? O SO não é o melhor para discussão / opinião subjetiva.