Search code examples
c++inheritancemetaprogrammingintrospection

Static introspection of method argument type in C++


I want to make a templated class which holds an instance of another class and forwards one of its foo methods with the correct argument type. Is there a clever meta-programming way of doing a "perfect forwarding" of the inner method?

template <typename Inner>
class Outer {
private:
  Inner inner;

public:

  // To-do: replicate foo method of Inner with identical signature,
  // how to pick correct T?
  void foo(T arg) { inner.foo(arg); }

};

I can see two classic solutions, but is there a better modern one with meta-programming?

  • Inheritance with partially protected interface: Outer could publicly inherit from Inner. But Inner also has methods which are only to be called by Outer and not the user. Those can be protected, ok, but it also tightly couples the implementations of Outer and all types of Inner classes. The public interface of Outer can be arbitrarily extended by public methods in Inner, which is not desired.
  • Make foo a templated function template <typename T> void foo(T&& arg) { inner.foo(std::forward<T>(arg)); }. This is perfect forwarding of the argument, but if a user calls foo with the wrong argument, the error reports Inner::foo instead of Outer::foo. This breaks the encapsulation provided by the public interface of Outer.

Solution

  • Something along these lines perhaps:

    template <typename Inner>
    class Outer : private Inner {
    public:
      using Inner::foo;
    };
    

    Demo