The following code is a dumbed down version of a wrapper around an object. I would like to be able to access the underlying Object
seamlessly, that is, without the need for parentheses, as the comments describe:
struct A
{
void Func() {}
};
template <typename Object>
struct ObjectWrapper
{
ObjectWrapper(Object& o) : object_(&o) {}
operator Object& () { return *object_; }
Object& operator ()() { return *object_; }
Object* object_;
};
int main()
{
A a;
ObjectWrapper<A> obj(a);
//
// Trying to call Func() on the A object that 'obj' wraps...
//
obj.operator A& ().Func(); // Messy
obj().Func(); // Better but still has parentheses
// I really want to be able to say this:
// obj.Func()
// ...but cannot see how!
}
Can anyone please suggest a way of doing this?
CodePudding user response:
I think you need overload operator ->
and/or *
(this is how smart pointers are done):
template <typename Object>
struct ObjectWrapper {
ObjectWrapper(Object& o)
: object_(&o)
{
LOG();
}
Object* operator->() const
{
LOG();
return object_;
}
Object& operator*() const
{
LOG();
return *object_;
}
Object* object_;
};
int main()
{
A a;
ObjectWrapper<A> obj { a };
obj->Func();
(*obj).Func();
}
https://godbolt.org/z/ErEbxWE4P
CodePudding user response:
Try by inheriting the Object
. See the void Func()
just redundant in the ObjectWrapper, only if you need some intercept logic:
struct A { void Func() {} };
template <typename Object> struct ObjectWrapper: public Object
{
ObjectWrapper(Object& o) : Object(o) {}
void Func() {cout<< "intercept Object::Func"; Object::Func();}
};
int main()
{
A a;
ObjectWrapper<A> obj(a);
obj.Func();
}
Also see in your code, use of &
in object_(&o)
ObjectWrapper(Object& o) : object_(&o) {}