Domanda

Ho tre chiamate di funzione che penso dovrebbero essere trattate (circa) allo stesso modo, ma chiaramente non lo sono. Sto cercando di capire perché uno dei tre non si compila (g ++ -std = c ++ 0x).

// Minimal example to reproduce a compile bug I want to understand.

#include <iostream>
#include <string>

using namespace std;


void bar(const string &&x) { cout << "bar: " << x << endl; }

string returns_a_string() { return string("cow"); }

int main( int argc, char *argv[] )
{
    bar(string("horse"));     // ok
    bar(returns_a_string());  // ok
    string aardvark = "aardvark";
    bar(aardvark);            // not ok, fails to compile, error in next comment
    /*
      rvalue-min.cpp:29:22: error: cannot bind ‘std::string {aka std::basic_string<char>}’ lvalue to ‘const string&& {aka const std::basic_string<char>&&}’
      rvalue-min.cpp:10:6: error:   initializing argument 1 of ‘void barR(const string&&)’
    */
}

Questa domanda è un po 'lungo le linee diC ++ 0x RIFERIMENTI RVALUE - LVALUES -RVALUE LINGAGGIO, Ma, se ha risposto lì, le mie scuse, non sono stato in grado di distillarlo.

Quello che voglio è essere in grado di chiamare la mia barra di funzione () con qualsiasi tipo di stringa e farlo funzionare. È abbastanza per definire void barR(const string &x), ma mi piacerebbe davvero capire perché.

Grazie mille per qualsiasi aiuto per capire perché la terza chiamata è diversa.

È stato utile?

Soluzione

Lo scopo dei parametri di riferimento del valore R è rilevare specificamente quando un oggetto è un valore R. Perché se un oggetto è un valore R, allora la funzione sa che non verrà più utilizzato, quindi può fare tutto ciò che vuole. Se un valore L potesse legarsi a un riferimento a valore R, ciò significherebbe che il rilevamento di cui stavo parlando non stava effettivamente avvenendo.

Se vuoi passare un valore L a una di queste funzioni, devi usare std::move. Passando un oggetto tramite std::move A una funzione che prende un riferimento a valore R è come dire: "Qui, prendi questo oggetto, strappa le sue viscere, non mi interessa cosa succede".

Per i tuoi scopi, la risposta corretta è quella di fare il riferimento a const parametri. Un valore R è perfettamente felice di essere legato a un riferimento const. Fatta eccezione per i costruttori di mossa, fare parametri di riferimento del valore R-valore non è quasi mai la cosa corretta da fare.

Altri suggerimenti

Devi usare std::move. Funziona bene:

bar(std::move(aardvark));
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top