#include <utility>
#include <cstdio>
#include <cmath>
template<typename Fn>
class Action {
Fn* function_ptr;
public:
Action() noexcept : function_ptr(nullptr) {
}
Action(std::nullptr_t) noexcept : function_ptr(nullptr) {
}
Action(const Action& other) : function_ptr(other.function_ptr) {
}
Action(Fn f) : function_ptr(f) {
}
Action& operator=(const Action& other) {
return (function_ptr = other.function_ptr, *this);
}
Action& operator=(std::nullptr_t ) {
return (function_ptr = nullptr, *this);
}
Action& operator=(Fn f) {
return (function_ptr = f, *this);
}
template<typename... Params>
auto operator()(Params&&... params) {
return function_ptr(std::forward<Params>(params)...);
}
};
void test(int i) {
printf("The given parameter is: %d\n", i);
}
int main() {
Action<decltype(printf)> pf_1;
pf_1 = nullptr;
pf_1 = printf;
Action<decltype(printf)> pf_2(pf_1);
pf_2("The value of Pi is: %.5f\n", M_PI);
Action<decltype(test)> test_fn(test);
test_fn(12);
return 0;
}
I2luY2x1ZGUgPHV0aWxpdHk+CiNpbmNsdWRlIDxjc3RkaW8+CiNpbmNsdWRlIDxjbWF0aD4KCnRlbXBsYXRlPHR5cGVuYW1lIEZuPgpjbGFzcyBBY3Rpb24gewogICAgRm4qIGZ1bmN0aW9uX3B0cjsKICAgIApwdWJsaWM6CiAgICBBY3Rpb24oKSBub2V4Y2VwdCA6IGZ1bmN0aW9uX3B0cihudWxscHRyKSB7CiAgICB9ICAgIAogICAgQWN0aW9uKHN0ZDo6bnVsbHB0cl90KSBub2V4Y2VwdCA6IGZ1bmN0aW9uX3B0cihudWxscHRyKSB7CiAgICB9ICAgIAogICAgQWN0aW9uKGNvbnN0IEFjdGlvbiYgb3RoZXIpIDogZnVuY3Rpb25fcHRyKG90aGVyLmZ1bmN0aW9uX3B0cikgewogICAgfSAgICAKICAgIEFjdGlvbihGbiBmKSA6IGZ1bmN0aW9uX3B0cihmKSB7CiAgICB9CgogICAgQWN0aW9uJiBvcGVyYXRvcj0oY29uc3QgQWN0aW9uJiBvdGhlcikgewogICAgICAgIHJldHVybiAoZnVuY3Rpb25fcHRyID0gb3RoZXIuZnVuY3Rpb25fcHRyLCAqdGhpcyk7CiAgICB9ICAgICAgICAgICAgCiAgICBBY3Rpb24mIG9wZXJhdG9yPShzdGQ6Om51bGxwdHJfdCApIHsKICAgICAgICByZXR1cm4gKGZ1bmN0aW9uX3B0ciA9IG51bGxwdHIsICp0aGlzKTsKICAgIH0gICAgCiAgICBBY3Rpb24mIG9wZXJhdG9yPShGbiBmKSB7CiAgICAgICAgcmV0dXJuIChmdW5jdGlvbl9wdHIgPSBmLCAqdGhpcyk7CiAgICB9CiAgICAKICAgIHRlbXBsYXRlPHR5cGVuYW1lLi4uIFBhcmFtcz4KICAgIGF1dG8gb3BlcmF0b3IoKShQYXJhbXMmJi4uLiBwYXJhbXMpIHsKICAgICAgICByZXR1cm4gZnVuY3Rpb25fcHRyKHN0ZDo6Zm9yd2FyZDxQYXJhbXM+KHBhcmFtcykuLi4pOwogICAgfQp9OwogICAgICAgIAp2b2lkIHRlc3QoaW50IGkpIHsKICAgIHByaW50ZigiVGhlIGdpdmVuIHBhcmFtZXRlciBpczogJWRcbiIsIGkpOwp9CgppbnQgbWFpbigpIHsKICAgIEFjdGlvbjxkZWNsdHlwZShwcmludGYpPiBwZl8xOwogICAgcGZfMSA9IG51bGxwdHI7ICAgIAogICAgcGZfMSA9IHByaW50ZjsKICAgIAogICAgQWN0aW9uPGRlY2x0eXBlKHByaW50Zik+IHBmXzIocGZfMSk7CiAgICBwZl8yKCJUaGUgdmFsdWUgb2YgUGkgaXM6ICUuNWZcbiIsIE1fUEkpOwogICAgCiAgICBBY3Rpb248ZGVjbHR5cGUodGVzdCk+IHRlc3RfZm4odGVzdCk7CiAgICB0ZXN0X2ZuKDEyKTsKICAgIAogICAgcmV0dXJuIDA7Cn0=