2016-03-30 9 views
9

In parole semplici Ho un semplice puntatore:non-const riferimento a un puntatore non-const punta all'oggetto const

int* a; 

ora, desidero cambiare il valore di questo puntatore. Voglio farlo in una funzione. La funzione assicura che non cambierà oggetto, a cui punta il puntatore, ma cambierà un puntatore stesso. Questo è il motivo per cui vorrei che questa funzione prendesse argomenti come: riferimento non const (poiché il valore del puntatore verrà modificato) al puntatore non-const (il puntatore stesso può essere modificato) puntando all'oggetto const (la funzione assicura, quell'oggetto, quel puntatore punta a non sarà cambiato).

La funzione più semplice sarebbe:

void function(const int*& a){ 
    a = 0; 
} 

ma quando provo a chiamare questa funzione:

int main(){ 
    int* a; 
    function(a); 
    return 0; 
} 

Compiler è infelice e dice:

l'inizializzazione non valida di non const riferimento di tipo 'const int * &' da un valore di tipo 'const int *' funzione (a);

Non riesco a capire questo errore, per quanto mi riguarda non c'è rvalue coinvolti (sto passando un riferimento all'oggetto, che esiste già in pila.)

domanda è, come posso farlo propriamente?

esempio può essere trovato qui: https://ideone.com/D45Cid


EDIT:

È stato suggerito, che la mia domanda è simillar al Why isn't it legal to convert "pointer to pointer to non-const" to a "pointer to pointer to const"

La mia domanda è diverso, come io non uso del puntatore per puntatore Io uso solo puntatore a oggetto/valore e memorizzo il riferimento ad esso, quindi situazione come nella risposta a questa domanda:

const char c = 'c'; 
char* pc; 
const char** pcc = &pc; // not allowed 
*pcc = &c; 
*pc = 'C';    // would allow to modify a const object 

È impossibile nel mio caso, in quanto non è possibile effettuare il dereferenziamento del puntatore di livello superiore (non ho un puntatore del genere).

Inoltre ho interrogato sulla soluzione bella e pulita a questo problema, che non è coperto in una domanda

+1

non sono sicuro se è possibile mescolare puntatore e riferimento. Beh, è ​​C++, dovresti, ma per favore non farlo. Nessuno capirà il tuo codice! – hr0m

+0

@Holt Non riesco a farlo. Questo è un semplice esempio, ma in codice reale in seguito eseguirò operazioni su questo oggetto, quindi non posso dichiarare puntatore come const – DawidPi

+0

@ hr0m Puntatore al puntatore è meglio, che puntatore a riferimento? Quelli a mio parere hanno significati diversi. – DawidPi

risposta

9

Non riesco a capire questo errore, per quanto mi riguarda non c'è rvalue coinvolti (sto passando un riferimento di opporsi, già esistente in pila.)

int* e const int* sono cose diverse. Quando si passa a di tipo int* a function(const int*&), è necessario convertirlo implicitamente in const int* innanzitutto, che è temporaneo, vale a dire valore non valido e non può essere associato a riferimento non const. Ecco perché il compilatore si lamenta.

La domanda è, come posso farlo correttamente?

Si potrebbe cambiare il tipo di a o il tipo di parametro di function() per renderli corrispondono esattamente (potrebbe essere const int* se non volete cambiare il valore indicato dal puntatore), al fine di evitare la conversione implicita e la variabile temporanea . O come suggerito da @TartanLlama, restituire il nuovo valore del puntatore da function().

+3

Un'altra opzione sarebbe quella di restituire il nuovo valore del puntatore, magari in una struct o in una coppia se esiste già un valore di ritorno. – TartanLlama

2

Non sono abbastanza sicuro di cosa si voglia raggiungere.

Questa parte di codice potrebbe aiutarti. Dovrebbe indicare come puoi fare ciò che vuoi.

#include <iostream> 

using namespace std; 

int A = 1; 
int B = 2; 
int C = 3; 

void change_pointer(int*& a){ 
    // your pointer will point to B 
    a = &B; 
} 

void change_value(int* const& a) { 
    // the reference to pointer is constant, but not the value 
    // a=&C; wouldn't work 
    *a = C; 
} 

int main(){ 
    int* a; 
    // at this point a is an undefined pointer to an int 
    // *a is unallocated space 

    a=&A; // you initialize the pointer with an other pointer 
    cout << "*a = " << *a << ", A = " << A << ", B = " << B << ", C = " << C << endl; 

    change_pointer(a); // makes 'a' point to B 
    cout << "*a = " << *a << ", A = " << A << ", B = " << B << ", C = " << C << endl; 

    change_value(a); // changes the value pointed by a to C (in the process modifying the value of B) 
    cout << "*a = " << *a << ", A = " << A << ", B = " << B << ", C = " << C << endl; 

    return *a; 
} 

EDIT: In risposta al commento di TartanLlama.

L'unico modo che posso vedere per lavorare con un "ref non const" ad un "puntatore non const" ad un "int const" è quello di utilizzare typedef:

#include <iostream> 

using namespace std; 

typedef const int const_int_t; 

const_int_t A = 1; 
const_int_t B = 2; 

void change_pointer(const_int_t*& a){ 
    // your pointer will point to B 
    a = &B; 
} 

int main(){ 
    const_int_t* a; 

    a=&A; // you initialize the pointer with an other pointer 
    cout << "*a = " << *a << ", A = " << A << ", B = " << B << endl; 

    change_pointer(a); // makes 'a' point to B 
    cout << "*a = " << *a << ", A = " << A << ", B = " << B << endl; 

    return *a; 
} 
+1

Questo non è ciò che l'OP vuole. Vuole un riferimento non-const a un puntatore non-const a un const 'int'. – TartanLlama

+0

@TartanLlama: grazie per aver chiarito le cose per me. Ho aggiunto una soluzione usando typedef. –

+1

Non è nemmeno quello che vuole, e il typedef non aggiunge nulla. Il problema è ottenere un riferimento non-const a un puntatore non-const a un const 'int' da un non-const poirter a non-const' int'. – TartanLlama