12

I'm wondering if it's possible to automatically forward a method call to an embedded object, without inheritance. For instance:

class embed
{
public:
    void embed_method() {return};
};

class container
{
public:
    void container_method() {return;}
private:
    embed obj;
};

int main()
{
    container object;

    object.container_method();  // Local method call
    object.embed_method();      // 'Forward' call, obviously doesn't work
}

It could be very useful when inheriting from a base class is not possible / not recommended. Currently, the only choice I have is to manually rewrite embed class methods into container class, and then call embed methods from container ones. Even if the process can be scripted, it's still annoying and it seems to be a bad solution.

Howli
  • 12,291
  • 19
  • 47
  • 72
JPC
  • 264
  • 2
  • 7
  • You might make `container` behave like a smart pointer and overload applicable operators (->, *) –  Jul 23 '14 at 16:44
  • http://stackoverflow.com/a/13885092/1147772 might help. Is private inheritance also out of question ? – Drax Jul 23 '14 at 16:44
  • @Drax yes, also out of question. – JPC Jul 23 '14 at 16:56
  • @DieterLücking I'll take a look, but I don't see how a smart pointer can help me in this case. Problem is that `embed` methods are still not defined in higher-level class (neither sp nor `container`). – JPC Jul 23 '14 at 16:59
  • I think you should rethink your design. Why do you want to expose the embedded object method? Maybe the code where you feel the need to call the embedded object method should be part of a method of the container object (e.g. Tell, don't ask)? – Rob K Jul 23 '14 at 17:16
  • It looks like you are trying to do things against C++ rules. Is the laziness of writing a wrapper method the only reason for doing that? – paceholder Apr 21 '16 at 16:52

2 Answers2

2
#include <utility>

class Embed {
 public:
  void embedMethod() { }
};

class Container {
 private:
  Embed embed;
 public:
  void containerMethod() {}

  template<typename ...Args, typename R>
  R forward( R (Embed::* function)(Args...), Args &&...args) {
    return (embed.*function)(std::forward<Args>(args)...);
  }
};

int main() {
  Container c;
  c.containerMethod();
  c.forward(&Embed::embedMethod);
}

Live demo.

I'm not condoning the design, it is very poor encapsulation.

Chris Drew
  • 14,926
  • 3
  • 34
  • 54
0
class embed
{
public:
    void embed_method(){return};
};

class container
{
public:
    void container_method(){return;}
    embed GetObj(){return obj;}

private:
    embed  obj;
};

int main()
{
    container object;

    object.container_method();  // Local method call
    object.GetObj().embed_method();     
}
Samer
  • 1,923
  • 3
  • 34
  • 54
  • 2
    the signature should be `embed& GetObj()` or `embed GetObj()` – clcto Jul 23 '14 at 16:48
  • @Samer Solution works but is not "user-friendly" (so sad that overloading `.` operator is forbidden...) – JPC Jul 23 '14 at 17:02
  • It is possible to overload the `operator()` of the parent class to get something like `object().embed_method() – paceholder Apr 21 '16 at 16:55