Até onde eu sei, não há razão para eu não poder passar uma referência a um ponteiro em C ++. No entanto, minhas tentativas de fazê-lo estão falhando e não faço ideia do porquê.
Isto é o que estou fazendo:
void myfunc(string*& val)
{
// Do stuff to the string pointer
}
// sometime later
{
// ...
string s;
myfunc(&s);
// ...
}
E eu estou recebendo este erro:
não é possível converter o parâmetro 1 de 'std :: string *' para 'std :: string * &'
string* const& val
vez 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.bind a temporary to the reference
é mais clara nesta resposta do que @Chris 'asreference to an actual string pointer in the calling scope, not an anonymous string pointer
. Independentemente disso, ambos provavelmente estão corretos da minha perspectiva.const string*&
estring* const&
na verdade são tipos diferentes. O primeiro é uma nãoconst
referência aconst string*
, enquanto o segundo é umaconst
referência astring*
.T const&
aconst T&
- como @Justin Time aponta, eles são tipos diferentes. Pode não têm consequências, por vezes, mas em outras situações será absolutamente crítico para preferir um ou outro, muito parecido com preferindoint
adouble
.Altere para:
EDITAR:
Isso é chamado
ref-to-pointer
e você não pode passar um endereço temporário como referência para a função. (a menos que sejaconst reference
).Porém, eu mostrei
std::string* pS = &s;
(ponteiro para uma variável local), seu uso típico seria: quando você quiser que o receptor altere o ponteiro em si, não o objeto para o qual ele aponta. Por exemplo, uma função que aloca memória e atribui o endereço do bloco de memória alocado ao argumento deve fazer referência a um ponteiro, ou um ponteiro ao ponteiro:fonte
&s
produz ponteiro temporário para string e você não pode fazer referência a objeto temporário.fonte
Experimentar:
ou
fonte
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.
&s
nã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ênciaconst
. Então, por exemplo, você não pode fazermas você pode fazer
Se você colocar uma declaração semelhante no cabeçalho da função, ela funcionará.
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 declaradoconst
no 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 ponteiros
, precisará defini-lo como emSe você deseja uma referência
s
ou um ponteiros
, faça o que é direto.fonte
Acabei de usar uma referência a um ponteiro para tornar todos os ponteiros em uma árvore binária excluída, exceto a raiz segura. Para tornar o ponteiro seguro, basta defini-lo como 0. Eu não poderia fazer com que a função que exclui a árvore (mantendo apenas a raiz) aceite um ref para um ponteiro, pois estou usando a raiz (este ponteiro) como o primeiro entrada para percorrer esquerda e direita.
Bottom line, uma referência a um ponteiro é inválida quando o parâmetro formal é o (this) ponteiro.
fonte
Bem-vindo às referências C ++ 11 e rvalue:
Agora você tem acesso ao valor do ponteiro (referido por
val
), que é o endereço da string.Você pode modificar o ponteiro e ninguém se importa. Esse é um aspecto do que é um rvalue em primeiro lugar.
Cuidado: o valor do ponteiro é válido apenas até o
myfunc()
retorno. Finalmente, é temporário.fonte
Sei que é possível passar referências de ponteiros, fiz isso na semana passada, mas não me lembro qual era a sintaxe, pois seu código parece correto para o meu cérebro agora. No entanto, outra opção é usar ponteiros de ponteiros:
fonte
myfunc ("string * & val") isso não faz sentido. "string * & val" implica "string val", * e & cancela um ao outro. Finalmente, não é possível passar a variável string para uma função ("string val"). Somente tipos de dados básicos podem ser passados para uma função, pois outros tipos de dados precisam passar como ponteiro ou referência. Você pode ter string & val ou string * val para uma função.
fonte