views:

256

answers:

4

hi!

I would like to pass a pointer by reference to a function, such that i can actually change the address the passed pointer is pointing to and i'd like to assign this argument a default value.

something like this:

in the declaration

void myFunc(SomeType* &var=NULL);

and the definition:

void MyClass::myFunc(SomeType* &var){
    if(var!=NULL)
        (*var)=(*someOtherPointer);

    if(someCondition)
        var=NULL;
}

such that a callee can decide whether he wants to call the function with one argument or without argument. And sucht that if he decides to pass an argument, and someCondition holds, the passed pointer will point to NULL afterwards

however - if i try to do it like this i get a:

Error C2440: 'default argument': 'int' cannot be conveted to 'SomeType *&'

Thanks for the help!

+7  A: 

NULL is not an lvalue - it cannot be passed by reference. It would be like passing 4 to a function that expects an int&.

The 'int' part is because NULL is a macro - defined 0.

Your best bet would be using a pointer to pass the pointer by reference, i.e. a double pointer. Then, if the parameter is NULL, nothing was passed. If not, it's the address of the pointer that should be modified [to point to NULL if someCondition holds].

aib
+1 You got it right so quickly ;)
AraK
insomnia be damned.
aib
Another option would be using boost::optional (no pun intended)
David Rodríguez - dribeas
... or just overload the function to provide a no-argument version.
Pavel Minaev
A: 

The error message says it all: you are passing an integer instead of a reference-to-a-pointer-to-SomeType. To do what you want, you can use a pointer-to-a-pointer-to-SomeType:

void myFunc(SomeType** var=NULL);

void MyClass::myFunc(SomeType** var){
    if(var!=NULL && *var!=NULL)
        (**var)=(*someOtherPointer);

    if(var!=NULL && someCondition)
        *var=NULL;
}
cwick
Unless "someCondition" includes "var!=NULL", you just accepted an answer that de-references a NULL pointer. Probably not what you wanted.
imaginaryboy
+1  A: 

You can also consider using boost::optional (not the simplest code you can use, but the option is there):

void f( boost::optional<int&> r = boost::optional<int&>() )
{
   if ( r ) *r = 5;
}
int main()
{
   int x = 0;
   f( x ); std::cout << x << std::endl; // 5, it did change the value
   f(); // compiler will default to an empty optional<int&> object
}
David Rodríguez - dribeas
+1 for the example.
Anders K.
+1  A: 

Ok, I can see why you'd do this from the perspective of exercising the C++ brain, but would you really do that in production code? It looks like an incredibly misty technique with side effects, when looking at the code as a colleague 1 year later. Did you think of using two separate functions with clear names, one returning a pointer and one doing any other needed work?

Johann Gerell