Domanda

Sto cercando di capire perché qualcuno avrebbe scritto una funzione che prende un riferimento rvalue const .

Nel seguente esempio di codice quale scopo è la funzione di riferimento rvalue const (ritorno "3"). E perché preferenza risoluzione di sovraccarico const rvalue sopra la funzione const di riferimento lvalue (ritorno "2").

#include <string>
#include <vector>
#include <iostream>

std::vector<std::string> createVector() { return std::vector<std::string>(); } 

//takes movable rvalue
void func(std::vector<std::string> &&p) { std::cout << "1"; }

//takes const lvalue
void func(const std::vector<std::string> &p)  { std::cout << "2"; }

//takes const rvalue???
//what is the point of const rvalue? if const I assume it is not movable?
void func(const std::vector<std::string> &&p) { std::cout << "3"; }

int main()
{
    func(createVector());
    return 0;
}
È stato utile?

Soluzione

lvalue fortemente preferiscono il legame con lvalue riferimenti e riferimenti simile rvalue fortemente preferiscono il legame con i riferimenti rvalue. espressioni modificabili debolmente preferiscono il legame con un riferimento non-const.

Così, quando il compilatore sta facendo la risoluzione di sovraccarico, si controlla se c'è un overload che accetta un riferimento rvalue, perché è preferito fortemente. In questo caso, poiché l'experssion è un rvalue modificabile, in modo che le vittorie di sovraccarico di riferimento rvalue.

V'è in realtà utilizzare per i riferimenti rvalue const, possono essere utilizzati per assicurarsi qualcosa di non si legano a un rvalue. Si ricordi che l'rvalue si lega ad un riferimento const lvalue, quindi se avete fatto:

template <typename T> void foo(const T& bar) { /* ... */ }

E chiamato la funzione con:

foo(createVector());

Sarebbe funzionano bene. Tuttavia a volte si desidera garantire che si può passare solo lvalue ad una funzione (questo è il caso per std::ref per uno). È possibile raggiungere questo obiettivo con l'aggiunta di un sovraccarico:

template <typename T> void foo(const T&&) = delete;

Ricordate, rvalues ??fortemente preferiscono il legame con i riferimenti rvalue, e le espressioni modificabili preferiscono debolmente legame con i riferimenti non-const. Dal momento che abbiamo un const rvalue riferimento, significa in sostanza che ogni singolo rvalue si legherà a questo, quindi, se si tenta di passare un rvalue per foo(), il compilatore darà un errore. Questo è l'unico modo per ottenere tale funzionalità, e quindi è talvolta utile.

Altri suggerimenti

risoluzione di sovraccarico preferisce rvalue const oltre lvalue const perché, beh, è ??un rvalue e si sta legandolo ad un riferimento rvalue, ma bisogna aggiungere const in entrambi i casi, riferimento in modo rvalue sicuramente preferito.

Queste cose sono generalmente pointless- è meglio lasciarli vincolante ai sovraccarichi lvalue const. rvalues ??const non hanno alcun reale utilizzo.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top