#include <functional>
class Foo
{
public:
void bar1(int )
{
/// No-op.
}
void bar2(const int &)
{
/// No-op.
}
void foo(int x)
{
_wrapper_bar1(x); /// No problems to deduce type
_wrapper_bar2(x); /// No problems to deduce type
_wrapper(&Foo::bar1, x);
_wrapper(&Foo::bar2, x);
}
private:
template <typename ...Args, typename ...Arg2s>
void _wrapper(void (Foo::*method) (Args ...), Arg2s&& ...args)
{
/// Do some common stuff here...
(this->*method)(std::forward<Arg2s>(args)...);
}
template <typename ...Args>
void _wrapper_bar1(Args && ...args)
{
bar1(std::forward<Args>(args)...);
}
template <typename ...Args>
void _wrapper_bar2(Args && ...args)
{
bar2(std::forward<Args>(args)...);
}
};
int main()
{
Foo().foo(123);
}
I2luY2x1ZGUgPGZ1bmN0aW9uYWw+CgpjbGFzcyBGb28KewpwdWJsaWM6CiAgICB2b2lkIGJhcjEoaW50ICkKICAgIHsKICAgICAgICAvLy8gTm8tb3AuCiAgICB9CgogICAgdm9pZCBiYXIyKGNvbnN0IGludCAmKQogICAgewogICAgICAgIC8vLyBOby1vcC4KICAgIH0KCiAgICB2b2lkIGZvbyhpbnQgeCkKICAgIHsKICAgICAgICBfd3JhcHBlcl9iYXIxKHgpOyAgICAgICAgICAgLy8vIE5vIHByb2JsZW1zIHRvIGRlZHVjZSB0eXBlCiAgICAgICAgX3dyYXBwZXJfYmFyMih4KTsgICAgICAgICAgIC8vLyBObyBwcm9ibGVtcyB0byBkZWR1Y2UgdHlwZQoKICAgICAgICBfd3JhcHBlcigmRm9vOjpiYXIxLCB4KTsgICAgCiAgICAgICAgX3dyYXBwZXIoJkZvbzo6YmFyMiwgeCk7ICAgIAogICAgfQoKcHJpdmF0ZToKICAgIHRlbXBsYXRlIDx0eXBlbmFtZSAuLi5BcmdzLCB0eXBlbmFtZSAuLi5Bcmcycz4KICAgIHZvaWQgX3dyYXBwZXIodm9pZCAoRm9vOjoqbWV0aG9kKSAoQXJncyAuLi4pLCBBcmcycyYmIC4uLmFyZ3MpCiAgICB7CiAgICAgICAgLy8vIERvIHNvbWUgY29tbW9uIHN0dWZmIGhlcmUuLi4KCiAgICAgICAgKHRoaXMtPiptZXRob2QpKHN0ZDo6Zm9yd2FyZDxBcmcycz4oYXJncykuLi4pOwogICAgfQoKICAgIHRlbXBsYXRlIDx0eXBlbmFtZSAuLi5BcmdzPgogICAgdm9pZCBfd3JhcHBlcl9iYXIxKEFyZ3MgJiYgLi4uYXJncykKICAgIHsKICAgICAgICBiYXIxKHN0ZDo6Zm9yd2FyZDxBcmdzPihhcmdzKS4uLik7CiAgICB9CgogICAgdGVtcGxhdGUgPHR5cGVuYW1lIC4uLkFyZ3M+CiAgICB2b2lkIF93cmFwcGVyX2JhcjIoQXJncyAmJiAuLi5hcmdzKQogICAgewogICAgICAgIGJhcjIoc3RkOjpmb3J3YXJkPEFyZ3M+KGFyZ3MpLi4uKTsKICAgIH0KfTsKCmludCBtYWluKCkKewogICAgRm9vKCkuZm9vKDEyMyk7Cn0K