views:

737

answers:

8

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 *&'

I'm probably making some stupid mistake somewhere, but I can't see what I'm doing wrong for the life of me.

A: 

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);
    // ...
}
Sake
For what I'm doing though, I need the address of the pointer as well as the pointer itself. I don't want to pass the pointer by value.
Alex
Still not understand what you try to accomplish. You cannot have "address of the pointer" of "string s", simply because "string s" is not a pointer.
Sake
@Alex: I take it that you need detect whether the string is exactly the same as another one you are storing and not just whether their contents are the same. If that is the case, note that you can use the address-of operator to a reference and it will get you the address of the referenced object: void f( std::string const }
David Rodríguez - dribeas
+3  A: 

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");

}
aJ
A: 

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)
Robert Gould
+2  A: 

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

n0rd
This is not quite true - you can make a reference to const temporary
1800 INFORMATION
+7  A: 

You function expects a reference to an actual pointer 'object':

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 it always points to an actual object.

Chris
You probably meant myfunc(_s)...
Ofek Shilon
Indeed, thanks for correcting that!
Chris
+13  A: 

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;
}
Michael Burr
+1  A: 

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.

Ari
A: 

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.

Shashikiran
Wrong on all levels. Please refresh your var declaration syntax.
Ari