#include <type_traits>
template <typename T>
class smart_ptr
{
public:
// ... removed other member functions for simplicity
T* get() const { return ptr; }
private:
template <typename... Args>
struct opparen_constret
{
typedef decltype(std::declval<T const>()(std::declval<Args>()...)) type;
};
template <typename... Args>
struct opparen_ret
{
typedef decltype(std::declval<T>()(std::declval<Args>()...)) type;
};
public:
template <typename... Args>
typename opparen_constret<Args...>::type operator ()(Args... args) const
{
return (*get())(args...);
}
template <typename... Args>
typename opparen_ret<Args...>::type operator ()(Args... args)
{
return (*get())(args...);
}
private:
T* ptr;
};
struct Test {};
int main()
{
smart_ptr<Test> p;
return 0;
}
I2luY2x1ZGUgPHR5cGVfdHJhaXRzPgoKdGVtcGxhdGUgPHR5cGVuYW1lIFQ+CmNsYXNzIHNtYXJ0X3B0cgp7CnB1YmxpYzoKICAgIC8vIC4uLiByZW1vdmVkIG90aGVyIG1lbWJlciBmdW5jdGlvbnMgZm9yIHNpbXBsaWNpdHkKICAgIFQqIGdldCgpIGNvbnN0IHsgcmV0dXJuIHB0cjsgfQogCnByaXZhdGU6CiAgICB0ZW1wbGF0ZSA8dHlwZW5hbWUuLi4gQXJncz4KICAgIHN0cnVjdCBvcHBhcmVuX2NvbnN0cmV0CiAgICB7CiAgICAgICAgdHlwZWRlZiBkZWNsdHlwZShzdGQ6OmRlY2x2YWw8VCBjb25zdD4oKShzdGQ6OmRlY2x2YWw8QXJncz4oKS4uLikpIHR5cGU7CiAgICB9OwogCiAgICB0ZW1wbGF0ZSA8dHlwZW5hbWUuLi4gQXJncz4KICAgIHN0cnVjdCBvcHBhcmVuX3JldAogICAgewogICAgICAgIHR5cGVkZWYgZGVjbHR5cGUoc3RkOjpkZWNsdmFsPFQ+KCkoc3RkOjpkZWNsdmFsPEFyZ3M+KCkuLi4pKSB0eXBlOwogICAgfTsKIApwdWJsaWM6CiAgICB0ZW1wbGF0ZSA8dHlwZW5hbWUuLi4gQXJncz4KICAgIHR5cGVuYW1lIG9wcGFyZW5fY29uc3RyZXQ8QXJncy4uLj46OnR5cGUgb3BlcmF0b3IgKCkoQXJncy4uLiBhcmdzKSBjb25zdAogICAgewogICAgICAgIHJldHVybiAoKmdldCgpKShhcmdzLi4uKTsKICAgIH0KIAogICAgdGVtcGxhdGUgPHR5cGVuYW1lLi4uIEFyZ3M+CiAgICB0eXBlbmFtZSBvcHBhcmVuX3JldDxBcmdzLi4uPjo6dHlwZSBvcGVyYXRvciAoKShBcmdzLi4uIGFyZ3MpCiAgICB7CiAgICAgICAgcmV0dXJuICgqZ2V0KCkpKGFyZ3MuLi4pOwogICAgfQogCnByaXZhdGU6CiAgICBUKiBwdHI7Cn07CiAKc3RydWN0IFRlc3Qge307CiAKaW50IG1haW4oKQp7CiAgICBzbWFydF9wdHI8VGVzdD4gcDsKICAgIHJldHVybiAwOwp9