I have a situation where I'm getting a reference to a pointer as a return type from a function. The reference is important, because I need the calling code to be able to modify the pointer.
But I also want to be able to return that through another function, this time cast to a ref-to-pointer of a derived type. This is causing a compiler error that I can't quite figure out how to get around.
This program shows what I'm trying to do:
#include <iostream>
class Foo
{
public:
virtual ~Foo() {}
};
class Bar : public Foo
{
public:
virtual ~Bar() {}
void doit() { std::cout << "Done" << std::endl; }
};
class Container
{
public:
void setFoo(Foo *f) { _foo = f; }
Foo*& getFoo() { return _foo; }
Foo *_foo;
};
class OtherContainer : public Container
{
public:
void setBar(Bar *b) { setFoo(dynamic_cast<Foo*>(b)); }
Bar*& getBar()
{
return static_cast<Bar*&>(getFoo());
}
};
int main(int argc, char *argv[])
{
OtherContainer container;
Bar bar;
Bar otherBar;
container.setBar(&bar);
container.getBar() = &otherBar;
return 0;
}
The compiler is returning this error:
g++ refptr.cc -o refptr
refptr.cc: In member function ‘Bar*& OtherContainer::getBar()’:
refptr.cc:41:20: error: invalid ‘static_cast’ from type ‘Foo*’ to type ‘Bar*&’
41 | return static_cast<Bar*&>(getFoo());
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~~
make: *** [<builtin>: refptr] Error 1
I've tried changing the static cast to just <Bar*> instead of <Bar*&> but then it says it "cannot bind non-const lvalue reference of type ‘Bar*&’ to an rvalue of type ‘Bar*’," which makes sense to me (and I didn't really expect that to work).
Is there even a way to achieve what I'm trying to do?
After some fooling around, I found that a way to get this to work is to turn the return value from the inner getter into a pointer. Then reinterpret_cast that and dereference for the return to the outer getter:
As explained in my answer to Passer By's comment, I can do this /only/ because (within the full context of what I'm making) I absolutely know that the stored pointer to the base class (Foo) is really a pointer to the derived class (Bar).
Edit
With help from commenters, I landed on a different solution. I want as much of type-checking on the way in as reasonable, with natural type presentation on the way out. I've modified my example code to be a little closer (contextually) to what I'm going for (e.g., a templated derived class). I am grateful for the critiques offered so far; thank you!
The template class OtherContainer is intended to be the outermost exposed class of the framework that this would be a part of. I think this approach should always work intuitively, regardless of compiler implementation...(or will it?)
Edit #2
I want to thank everybody who took the time to comment on my question and proposed self-answer. I am a stubborn badger when it comes to giving up on an idea, but y'all have convinced me that this particular idea won't work the way I currently have it conceived. I need to find a different way to accomplish what I'm after. Thank you all.