convert reference to pointer representation in C++
Asked Answered
P

6

46

Is there a way to "convert" a reference to pointer in c++? In example below, func2 has already defined prototype and I can't change it, but func is my API, and I'd like to either pass both parameters, or one (and second set to NULL) or neither (both set to NULL):

void func2(some1 *p1, some2 *p2);

func(some1& obj, some2& obj2)
{
   func2(..);
}
Photoemission answered 26/9, 2013 at 15:31 Comment(9)
"&", same as for non references. As in func2(&obj, &obj2)Szombathely
You can take the address of a reference. It gives you the address of the referred-to object. I.e. you may do func2(&obj1, NULL). Note that there is no way to pass NULL to func; there is no such thing as a NULL reference.Hospodar
@BoBTFish, NULL references are easy to create. int* pi = 0; int& ri = π. Of course that's naughty, but not impossible and sometimes done by accident.Halimeda
@Ben: That's not creating NULL reference, that's creating undefined behavior.Butterball
It is illegal. What you create is not a NULL reference. It is an abomination. It is Undefined. It is likely to invoke Nasal Demons. It does not exist.Hospodar
@BenjaminLindley, .... and yet I got them as return values from a library I was using and didn't have source code for... I had to check for them by taking the address and comparing to null. No, you shouldn't do it. But that doesn't mean someone won't do it to you.Halimeda
@BoBTFish, Oh, it exists all right.... (shudders)... you wouldn't believe the things I've seen... just ... don't ask me to go back there, that's all.Halimeda
@Ben: There is no valid way to check for such a thing. In the example you provide where you "create a NULL reference", there is no guarantee about the value of &ri, and so comparing it against nullptr or NULL is fruitless. It may have appeared to work as you expected in particular situations, but there is no guarantee of it working in other implementations, or in the same implementation at different times. Undefined behavior sometimes means behaving exactly as you expect.Butterball
@BenjaminLindley, that's like saying crime can't exist because it's illegal. Just because something isn't guaranteed by the standard to work on all compilers, doesn't mean it is fruitless. Far from it... is there yet any compiler which implements the whole standard???Halimeda
A
46

func2(&obj, &obj2);

Use reference parameters like normal variables.

Augmenter answered 26/9, 2013 at 15:33 Comment(0)
S
17

Just get the address of the object.

some1 *p = &obj;

Or in your case:

func2(&obj, &obj2);
Shelly answered 26/9, 2013 at 15:33 Comment(5)
Well, I see what you're trying to do, but some1& obj; is wrong. You can't create a reference that does not reference anything.Caldeira
Also, this doesn't take the address of the reference, but the address of what it refers to. References don't have addresses because it is unspecified whether or not references require storage.Seibold
Sorry, that wasn't meant to be a statement. I just copied how the variable was declared in the OP's code.Shelly
@bstamour: You are correct, but it seems clear to me that the OP wants the address of the original value. He just wants to treat it as a pointer.Shelly
Right. I was more commenting on your original language, when you said "get the address of the reference", which is something that doesn't exist.Seibold
S
13

In normal cases, you can simply use &:

void func(some1& obj, some2& obj2)
{
    func2(&obj, &obj2);
}

but operator& might be overloaded, so std::addressof (since C++11) should be used for those cases:

void func(some1& obj, some2& obj2)
{
    func2(std::addressof(obj), std::addressof(obj2));
}
Scruggs answered 23/8, 2018 at 15:55 Comment(0)
B
5
 func2(&obj, &obj2);

is what you should use.

Bellina answered 26/9, 2013 at 15:35 Comment(0)
C
0

For a clean design put all in a class (or use namespaces)

class X {
   private:
   void func2(someA*, someB*);

   public:
   func(someA& a, someB& b) { func2(&a, &b); }
   func(someA& a) { func2(&a, 0); }
   func() { func2(0, 0); }
}
Carbuncle answered 26/9, 2013 at 15:42 Comment(0)
R
0

Cast the function to a new function:

void func2(some1 *p1, some2 *p2);
//Just add the following line of code:
void (*func)(some1&,some2&) = (void(*)(some1&,some2&))&func2;

int main() 
{
    some1 obj();
    some2 obj2();
    func(obj,obj2);
}
Riposte answered 16/2 at 11:28 Comment(1)
Clever, but too clever for my taste. This is technically UB, and trips the undefined behavior sanitizer (which alone is a reason to avoid it, IMO).Nightmare

© 2022 - 2024 — McMap. All rights reserved.