[c++] Passing references to pointers in C++

As far as I can tell, there's no reason I shouldn't be allowed to pass a reference to a pointer in C++. However, my attempts to do so are failing, and I have no idea why.

This is what I'm doing:

void myfunc(string*& val)
{
    // Do stuff to the string pointer
}

// sometime later 
{
    // ...
    string s;
    myfunc(&s);
    // ...
}

And I'm getting this error:

cannot convert parameter 1 from 'std::string *' to 'std::string *&'

This question is related to c++ pointers reference

The answer is


Your function expects a reference to an actual string pointer in the calling scope, not an anonymous string pointer. Thus:

string s;
string* _s = &s;
myfunc(_s);

should compile just fine.

However, this is only useful if you intend to modify the pointer you pass to the function. If you intend to modify the string itself you should use a reference to the string as Sake suggested. With that in mind it should be more obvious why the compiler complains about you original code. In your code the pointer is created 'on the fly', modifying that pointer would have no consequence and that is not what is intended. The idea of a reference (vs. a pointer) is that a reference always points to an actual object.


Try:

void myfunc(string& val)
{
    // Do stuff to the string pointer
}

// sometime later 
{
    // ...
    string s;
    myfunc(s);
    // ...
}

or

void myfunc(string* val)
{
    // Do stuff to the string pointer
}

// sometime later 
{
    // ...
    string s;
    myfunc(&s);
    // ...
}

Welcome to C++11 and rvalue references:

#include <cassert>
#include <string>

using std::string;

void myfunc(string*&& val)
{
    assert(&val);
    assert(val);
    assert(val->c_str());
    // Do stuff to the string pointer
}

// sometime later 
int main () {
    // ...
    string s;
    myfunc(&s);
    // ...
}

Now you have access to the value of the pointer (referred to by val), which is the address of the string.

You can modify the pointer, and no one will care. That is one aspect of what an rvalue is in the first place.

Be careful: The value of the pointer is only valid until myfunc() returns. At last, its a temporary.


I know that it's posible to pass references of pointers, I did it last week, but I can't remember what the syntax was, as your code looks correct to my brain right now. However another option is to use pointers of pointers:

Myfunc(String** s)

Change it to:

  std::string s;
  std::string* pS = &s;
  myfunc(pS);

EDIT:

This is called ref-to-pointer and you cannot pass temporary address as a reference to function. ( unless it is const reference).

Though, I have shown std::string* pS = &s; (pointer to a local variable), its typical usage would be : when you want the callee to change the pointer itself, not the object to which it points. For example, a function that allocates memory and assigns the address of the memory block it allocated to its argument must take a reference to a pointer, or a pointer to pointer:

void myfunc(string*& val)
{
//val is valid even after function call
   val = new std::string("Test");

}

I have just made use of a reference to a pointer to make all the pointers in a deleted binary tree except the root safe. To make the pointer safe we just have to set it to 0. I could not make the function that deletes the tree (keeping only the root) to accept a ref to a pointer since I am using the root (this pointer) as the first input to traverse left and right.

void BinTree::safe_tree(BinTree * &vertex ) {
    if ( vertex!=0 ) {  // base case
        safe_tree(vertex->left);    // left subtree.
            safe_tree(vertex->right);   //  right subtree.
          // delete vertex;  // using this delete causes an error, since they were deleted on the fly using inorder_LVR. If inorder_LVR does not perform delete to the nodes, then, use delete vertex;
        vertex=0;  // making a safe pointer
    }
} // end in

Bottom line, a reference to a pointer is invalid when the formal parameter is the (this) pointer.


EDIT: I experimented some, and discovered thing are a bit subtler than I thought. Here's what I now think is an accurate answer.

&s is not an lvalue so you cannot create a reference to it unless the type of the reference is reference to const. So for example, you cannot do

string * &r = &s;

but you can do

string * const &r = &s;

If you put a similar declaration in the function header, it will work.

void myfunc(string * const &a) { ... }

There is another issue, namely, temporaries. The rule is that you can get a reference to a temporary only if it is const. So in this case one might argue that &s is a temporary, and so must be declared const in the function prototype. From a practical point of view it makes no difference in this case. (It's either an rvalue or a temporary. Either way, the same rule applies.) However, strictly speaking, I think it is not a temporary but an rvalue. I wonder if there is a way to distinguish between the two. (Perhaps it is simply defined that all temporaries are rvalues, and all non-lvalues are temporaries. I'm not an expert on the standard.)

That being said, your problem is probably at a higher level. Why do you want a reference to the address of s? If you want a reference to a pointer to s, you need to define a pointer as in

string *p = &s;
myfunc(p);

If you want a reference to s or a pointer to s, do the straightforward thing.


myfunc("string*& val") this itself doesn't make any sense. "string*& val" implies "string val",* and & cancels each other. Finally one can not pas string variable to a function("string val"). Only basic data types can be passed to a function, for other data types need to pass as pointer or reference. You can have either string& val or string* val to a function.


&s produces temporary pointer to string and you can't make reference to temporary object.


The problem is that you're trying to bind a temporary to the reference, which C++ doesn't allow unless the reference is const.

So you can do one of either the following:

void myfunc(string*& val)
{
    // Do stuff to the string pointer
}


void myfunc2(string* const& val)
{
    // Do stuff to the string pointer
}

int main()
// sometime later 
{
    // ...
    string s;
    string* ps = &s;

    myfunc( ps);   // OK because ps is not a temporary
    myfunc2( &s);  // OK because the parameter is a const&
    // ...

    return 0;
}

Examples related to c++

Method Call Chaining; returning a pointer vs a reference? How can I tell if an algorithm is efficient? Difference between opening a file in binary vs text How can compare-and-swap be used for a wait-free mutual exclusion for any shared data structure? Install Qt on Ubuntu #include errors detected in vscode Cannot open include file: 'stdio.h' - Visual Studio Community 2017 - C++ Error How to fix the error "Windows SDK version 8.1" was not found? Visual Studio 2017 errors on standard headers How do I check if a Key is pressed on C++

Examples related to pointers

Method Call Chaining; returning a pointer vs a reference? lvalue required as left operand of assignment error when using C++ Error: stray '\240' in program Reference to non-static member function must be called How to convert const char* to char* in C? Why should I use a pointer rather than the object itself? Function stoi not declared C pointers and arrays: [Warning] assignment makes pointer from integer without a cast Constant pointer vs Pointer to constant How to get the real and total length of char * (char array)?

Examples related to reference

Method Call Chaining; returning a pointer vs a reference? When to create variables (memory management) Reference to non-static member function must be called Cannot find reference 'xxx' in __init__.py - Python / Pycharm c++ "Incomplete type not allowed" error accessing class reference information (Circular dependency with forward declaration) C++ initial value of reference to non-const must be an lvalue Dependent DLL is not getting copied to the build output folder in Visual Studio How to write to error log file in PHP How to reference Microsoft.Office.Interop.Excel dll? Linker Error C++ "undefined reference "