Edição: Eu experimentei alguns, e descobri coisas são um pouco mais sutis do que eu pensava. Aqui está o que agora acho que é uma resposta precisa.
&snão é um valor l, portanto você não pode criar uma referência a ele, a menos que o tipo da referência seja referência const. Então, por exemplo, você não pode fazer
string * &r = &s;
mas você pode fazer
string * const &r = &s;
Se você colocar uma declaração semelhante no cabeçalho da função, ela funcionará.
void myfunc(string * const &a) { ... }
Há outra questão, a saber, temporários. A regra é que você pode obter uma referência a um temporário apenas se for const. Portanto, nesse caso, pode-se argumentar que & s é temporário e, portanto, deve ser declarado constno protótipo de função. Do ponto de vista prático, não faz diferença neste caso. (É um rvalue ou um temporário. De qualquer forma, a mesma regra se aplica.) No entanto, estritamente falando, acho que não é um temporário, mas um rvalor. Gostaria de saber se existe uma maneira de distinguir entre os dois. (Talvez seja simplesmente definido que todos os temporários são rvalores e todos os não-valores são temporários. Não sou especialista no padrão.)
Dito isto, seu problema provavelmente está em um nível superior. Por que você deseja uma referência ao endereço de s? Se você quiser uma referência a um ponteiro s, precisará defini-lo como em
string *p = &s;
myfunc(p);
Se você deseja uma referência sou um ponteiro s, faça o que é direto.
string* const& valvez de um equivalente menos legível como por exemploconst string* &val. Aos meus olhos, isso é claramente uma referência constante , a um ponteiro, a uma corda. Pessoalmente, prefiro escrever emT const&vez deconst T&em declarações para obter esse esclarecimento exato.