Neste artigo do blog do Visual C ++ sobre referências de rvalue :
... C ++ não deseja que você modifique temporariamente acidentalmente, mas chamar diretamente uma função de membro que não seja const em um rvalue modificável é explícito, portanto é permitido ...
Basicamente, você não deve tentar modificar temporários pela mesma razão de que eles são objetos temporários e morrerão a qualquer momento. A razão pela qual você pode chamar métodos não-const é que, bem, você é bem-vindo a fazer algumas coisas "estúpidas", desde que saiba o que está fazendo e seja explícito (como usar reinterpret_cast). Mas se você vincular um temporário a uma referência que não seja const, poderá continuar transmitindo-o "para sempre" apenas para que sua manipulação do objeto desapareça, porque em algum momento ao longo do caminho você esqueceu completamente que isso era temporário.
Se eu fosse você, repensaria o design de minhas funções. Por que g () está aceitando referência, ele modifica o parâmetro? Se não, faça const const, se sim, por que você tenta passar temporariamente para ele, você não se importa que seja um temporário que você está modificando? Por que getx () está retornando temporário de qualquer maneira? Se você compartilhar seu cenário real e o que está tentando realizar, poderá obter boas sugestões sobre como fazê-lo.
Ir contra a linguagem e enganar o compilador raramente resolve problemas - geralmente ele cria problemas.
Editar: Responder a perguntas no comentário: 1)
X& x = getx().ref(); // OK when will x die?
- Não sei e não ligo, porque é exatamente isso que quero dizer com "ir contra a linguagem". A linguagem diz que "os temporários morrem no final da declaração, a menos que sejam obrigados a const const, caso em que morrem quando a referência sai do escopo". Aplicando essa regra, parece que x já está morto no início da próxima instrução, pois não está vinculado à referência const (o compilador não sabe o que ref () retorna). Este é apenas um palpite, no entanto.
2) Eu declarei o objetivo claramente: você não tem permissão para modificar temporários, porque simplesmente não faz sentido (ignorando as referências de valor C ++ 0x rvalue). A pergunta "então por que tenho permissão para chamar membros não-constantes?" é bom, mas não tenho uma resposta melhor do que a que eu já afirmei acima.
3) Bem, se eu estou certo sobre x ao X& x = getx().ref();
morrer no final da declaração, os problemas são óbvios.
De qualquer forma, com base em suas perguntas e comentários, acho que nem essas respostas extras o satisfarão. Aqui está uma tentativa / resumo final: O comitê C ++ decidiu que não faz sentido modificar temporários; portanto, eles não permitiam a ligação a referências não constantes. Pode haver alguma implementação do compilador ou problemas históricos também envolvidos, não sei. Então, surgiu um caso específico, e foi decidido que, apesar de todas as probabilidades, eles ainda permitirão a modificação direta através da chamada do método não-const. Mas isso é uma exceção - geralmente você não tem permissão para modificar temporários. Sim, o C ++ costuma ser tão estranho.