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 fromInner
. But Inner also has methods which are only to be called by Outer and not the user. Those can beprotected
, ok, but it also tightly couples the implementations ofOuter
and all types ofInner
classes. The public interface ofOuter
can be arbitrarily extended by public methods inInner
, 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 callsfoo
with the wrong argument, the error reportsInner::foo
instead ofOuter::foo
. This breaks the encapsulation provided by the public interface ofOuter
.