Question

I have a class FooBar that contains a member of type Foo. This type can be inherited from so that FooBar has variable behaviour. Foo contains multiple overloads for the accessor method bar.

class FooBar;

class Foo{
    friend class FooBar;

    virtual void bar(int barIn){ bar_ = barIn; }
    virtual void bar(int barIn, float barScale){ bar(int(barIn * barScale)); }
    virtual void bar(const Foo& barSource){ bar(barSource.bar_); }
    int bar(){ return bar_; }

    int bar_;
};

class FooBar{
public:
    void bar(int barIn){ foo_.bar(barIn); }
    void bar(int barIn, float barScale){ foo_.bar(barIn, barScale); }
    void bar(const Foo& barSource){ foo_.bar(barSource); }
    int bar(){ return foo_.bar(); }
private:
    Foo& foo_;
};

Looks ok so far, but I feel like all the definitions for the FooBar.bar accessor are kind of unnecessary. I know that the compiler inlines them, so there should be no overhead, but the methods all got the same name and are all overloads of each other.

Is there a way in C++ to "export" (I haven't found a better word) the accessor so calls to FooBar.bar are just redirected to FooBar.foo_.bar?

One idea I had was overriding the operator -> for FooBar, but the real case has multiple classes like Foo, so that would only work for one of them.

Was it helpful?

Solution

You could write a real generic forwarder:

class FooBar
{
public:
    template<typename... Args>
    auto bar(Args&&... args) -> decltype(foo_.bar(std::forward<Args>(args)...))
    {
        return foo_.bar(std::forward<Args>(args)...);
    }

private:
    Foo& foo_;
};

(this requires C++11, with C++14 you could even leave out the ->decltype... part)

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top