11

In simple words I have a simple pointer:

int* a; 

now, I would like to change value of this pointer. I want to do this in a function. Function assures, that it will not change object, that pointer points to, but will change a pointer itself. This is why I would like this function to take argument like: non-const reference (because value of pointer will be changed) to the non-const pointer(pointer itself can be changed) pointing to const object (function assures, that object, that pointer points to will not be changed).

The simplest function would be:

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

but when I try to call this function:

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

Compiler is unhappy and says:

invalid initialization of non-const reference of type 'const int*&' from an rvalue of type 'const int*' function(a);

I cannot quite understand this error, as for me there is no rvalue involved (I am passing a reference to object, that already exists on the stack.)

Question is, how can I do it properly?

Example can be found here: https://ideone.com/D45Cid


EDIT:

It was suggested, that my question is simillar to the Why isn't it legal to convert "pointer to pointer to non-const" to a "pointer to pointer to const"

My question is different as I do not use pointer to pointer I use only pointer to object/value and store reference to it, therefore situation like in the answer to that question:

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

Is impossible in my case, as I cannot dereference the top level pointer (I do not have such a pointer).

Moreover I questioned about nice and clean solution to this problem, which is not covered in a question

12
  • 1
    i am not sure if you can mix up pointer and a reference. Well it's c++ you should, but please don't. Nobody will understand your code! Commented Mar 30, 2016 at 7:20
  • @Holt I cannot do this. This is simple example, but in real code later I am doing operations on this object, so I cannot declare pointer as const Commented Mar 30, 2016 at 7:21
  • @hr0m Pointer to the pointer is better, than pointer to reference? Those in my opinion have different meanings. Commented Mar 30, 2016 at 7:24
  • 3
    @hr0m I don't see what's wrong with a reference to a pointer. If you want to take in a pointer and modify it then a reference to a pointer is the natural way to do so. Taking a pointer to the pointer you want to modify implies that it could be null, which is not the case with a reference. Commented Mar 30, 2016 at 7:28
  • 1
    @hr0m: Just because you are unfamilliar wiht something doesn't mean it is bad practice. And a reference of a pointer is something that should really be understood by any c++ programmer. In particular, I don't see, why a double pointer should be more understandable. Commented Mar 30, 2016 at 8:46

2 Answers 2

9

I cannot quite understand this error, as for me there is no rvalue involved (I am passing a reference to object, that already exists on the stack.)

int* and const int* are different things. When you pass a of type int* to function(const int*&), it need to be implicitly casted to const int* firstly, which is temporary, i.e. rvalue, and couldn't be bound to non-const referece. That's why compiler complains.

Question is, how can I do it properly?

You could change the type of a or the parameter type of function() to make them match exactly (might be const int* if you won't change the value pointed by the pointer), to avoid the implicit conversion and temporary variable. Or as @TartanLlama suggested, return the new value of pointer from function().

Sign up to request clarification or add additional context in comments.

1 Comment

Another option would be to return the new value of the pointer, maybe in a struct or pair if there is already a return value.
2

I'm not quite sure what it is you want to achieve.

This piece of code might help you, though. It should point to how you can do what you want.

#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 answer to TartanLlama's comment.

The only way I can see to work with a "non const ref" to a "non const pointer" to a "const int" is by using 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; } 

3 Comments

This isn't what OP wants. He wants a non-const reference to a non-const pointer to a const int.
@TartanLlama: thanks for clearing up things for me. I added a solution using typedef.
That's not what he wants either, and the typedef doesn't add anything. The problem is getting a non-const reference to a non-const pointer to a const int from a non-const poirter to non-const int .

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.