2013-03-05 4 views
17

È possibile utilizzare qualcosa come generate_n per creare un numero const vector di, diciamo, casuale? Non riuscivo a pensare a un modo per farlo senza derivare vector e facendo il compito nel costruttore.Come si inizializza un vettore const dei risultati di una funzione utilizzando C++ 11?

+2

So che avete una risposta per questo ora, ma appena cronaca derivante 'VECTOR' (o di altro tipo in' lo spazio dei nomi di std' non specificamente inteso per essere derivato) è [rischioso] (http://stackoverflow.com/questions/2034916/is-it-okay-to-inherit-implementation-from-stl-containers-rather-than-delegate – boycy

risposta

26

Utilizzare un helper statico o un lambda se lo si desidera; spostare la semantica/copiare l'elisione come indicato nei commenti renderà questo piuttosto economico poiché tutti i compilatori decenti ometteranno una copia completa del vettore restituito dall'assistente. Invece creeranno semplicemente il codice per riempire un singolo vettore e quindi utilizzarlo.

std::vector<int> Helper() 
{ 
    const size_t n = 10; 
    std::vector<int> x(n); 
    std::generate_n(x.begin(), n, someGenerator); 
    return x; 
} 

const std::vector<int> my_const_vec(Helper()); 

Ecco la versione lambda:

const std::vector<int> my_const_vec([]() 
    { 
    const size_t n = 10; 
    std::vector<int> x(n); 
    std::generate_n(x.begin(), n, someGenerator); 
    return x; 
    }()); 
+1

Con un helper così semplice, la maggior parte dei compilatori riuscirà persino a eliminare completamente la copia. – Agentlien

+2

A proposito, secondo lo standard * current * il tuo lambda ha bisogno di un '-> std :: vector ', penso. –

+0

hmm ora sono confuso. Provato con gcc4.7 e cl17.00 e entrambi lo accettano, ma in effetti mi sembra di ricordare che le precedenti versioni di entrambi avrebbero rifiutato. – stijn

0

incapsulare il tuo inizializzazione in una funzione e ve l'annunzierà "constexpr" in modo che si può utilizzare per inizializzare un espressione const.

+3

Non c'è bisogno di un 'constexpr' qui, dal momento che non ha bisogno di un'espressione costante di tempo di compilazione (che un ritorno' std :: vector' non può mai essere, comunque). –

0

È possibile utilizzare std::transform così

vector<int> vec(10,1); 
transform(vec.begin(), vec.end(), vec.begin(), func); 

Dove func è:

int func(int i) 
{ 
//return a random generated number 
} 
+0

è possibile, ma l'OP richiede un singolo vettore * const *. – stijn

+0

@stijn Ohh si. Ma potrei usare un vettore intermedio temporaneo e poi assegnarlo al vettore 'const' come anche il tuo approccio ne creò uno nella funzione chiamata. – Saksham