c++ tutorialspoint Référence non-const à un pointeur non-const pointant vers l'objet const




pointers traduction (2)

En termes simples, j'ai un pointeur simple:

int* a;

maintenant, je voudrais changer la valeur de ce pointeur. Je veux le faire dans une fonction. La fonction assure qu'il ne changera pas d'objet, pointé vers, mais changera un pointeur lui-même. C'est pourquoi je voudrais que cette fonction prenne des arguments comme: la référence non-const (parce que la valeur du pointeur sera changée) au pointeur non-const (le pointeur lui-même peut être changé) pointant vers l'objet const (la fonction assure, ce pointeur ne sera pas modifié).

La fonction la plus simple serait:

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

mais quand j'essaie d'appeler cette fonction:

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

Le compilateur est mécontent et dit:

initialisation invalide de la référence non-const de type 'const int * &' à partir d'une valeur de type 'const int *' de type (a);

Je n'arrive pas à comprendre cette erreur, car pour moi il n'y a pas de rvalue impliquée (je passe une référence à l'objet, qui existe déjà sur la pile).

La question est, comment puis-je le faire correctement?

Exemple peut être trouvé ici: https://ideone.com/D45Cid

MODIFIER:

Il a été suggéré, que ma question est similaire à la Pourquoi n'est-il pas légal de convertir "pointeur en pointeur en non-const" en pointeur en pointeur en const?

Ma question est différente car je n'utilise pas de pointeur vers un pointeur. J'utilise seulement un pointeur vers un objet / une valeur et je stocke des références à celui-ci, donc une situation comme dans la réponse à cette question:

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

Est impossible dans mon cas, car je ne peux pas déréférencer le pointeur de niveau supérieur (je n'ai pas un tel pointeur).

De plus, j'ai questionné sur une solution propre et agréable à ce problème, qui n'est pas couverte par une question


Je ne suis pas sûr de ce que vous voulez accomplir.

Ce morceau de code pourrait vous aider, cependant. Cela devrait indiquer comment vous pouvez faire ce que vous voulez.

#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: En réponse au commentaire de TartanLlama.

La seule façon dont je peux voir fonctionner avec un "non const ref" vers un "non const pointeur" vers un "const int" est en utilisant 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;
}

Je n'arrive pas à comprendre cette erreur, car pour moi il n'y a pas de rvalue impliquée (je passe une référence à l'objet, qui existe déjà sur la pile).

int* et const int* sont des choses différentes. Lorsque vous passez a de type int* à function(const int*&) , il doit être implicitement casté en const int* premièrement, ce qui est temporaire, c'est-à-dire rvalue, et ne peut pas être lié à une référence non-const. C'est pourquoi le compilateur se plaint.

La question est, comment puis-je le faire correctement?

Vous pouvez changer le type de a ou le type de paramètre de function() pour les faire correspondre exactement (peut être const int* si vous ne changez pas la valeur pointée par le pointeur), pour éviter la conversion implicite et la variable temporaire. Ou comme suggéré par @TartanLlama, renvoyez la nouvelle valeur de pointeur à partir de function() .







reference