Como evitar explicitamente chamar um construtor ao passar objeto temporário por referência em C ++?

StackOverflow https://stackoverflow.com/questions/1008272

  •  06-07-2019
  •  | 
  •  

Pergunta

Vamos dizer que eu tenho uma classe:

class String
{
public:
     String(char *str);
};

E duas funções:

void DoSomethingByVal(String Str);
void DoSomethingByRef(String &Str);

Se eu chamar DoSomethingByVal assim:

DoSomethingByVal("My string");

os números do compilador fora que ele deve criar um objeto String temporário e chamar o char * construtor.

No entanto, se eu tento usar DoSomethingByRef da mesma forma, eu recebo um "Não é possível converter parâmetro de 'char *' para 'String &'" erro.

Em vez disso, eu tenho que criar explicitamente uma instância:

DoSomethingByRef(String("My string"));

que pode ficar preety irritante.

Existe alguma maneira de evitar isso?

Foi útil?

Solução

Você precisa passar por referência const:

Para:

void DoSomethingByVal(String Str);

Nesta situação, o compilador primeiro cria uma variável temporária. Então, a variável temporário é cópia construído no parâmetro.

Para:

void DoSomethingByRef(String const& Str);

Nesta situação, o compilador cria uma variável temporária. Mas variáveis ??temporárias não pode ser vinculado a uma referência que só pode ser vinculado a uma referência const para que a sua função original não pode ser chamado. Observe o std :: string objetos construtor recebe uma referência const é o parâmetro para o construtor de cópia e é por isso que a primeira versão funciona como o temporário é ligado ao parâmetro de referência const do construtor de cópia única.

Outras dicas

Hmm, eu não tenho certeza se

void DoSomethingByRef(String &Str);
DoSomethingByRef(String("My string"));

seria realmente compilar. Um rvalue não pode ligar-se a uma referência a não-const (porque um ref para não-const está declarando que você vai modificar o valor, e não faria sentido para modificar um temporário). Tem certeza de que não está fazendo:

String str("My string");
DoSomethingByRef(str);

Se você quiser DoSomethingByVal tomar um rvalue, o parâmetro tem de ser uma referência para const:

void DoSomethingByRef(const String &Str);

Marca:

DoSomethingByRef (const string & str);

"My String" não é uma String, que é um c-corda, um char *, se você quiser. Você precisa colocar isso c-string em um objeto String, e então você pode passar o novo objeto String por referência.

Outro ponto, você já está passando um char * ... isso é muito leve, apenas um ponteiro. Por que se preocupar com a passagem de um novo objeto por referência? Apenas alocar um novo objeto dentro daquele construtor da pilha e copiar o c-corda para ele.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top