#include <iostream>
#include <type_traits>

template<typename T>
class ptr {
	T* m_ptr;
    public:
		ptr(T* a_ptr) : m_ptr(a_ptr) {}

		template<typename U = T>
		typename
			std::enable_if<!std::is_same<U, void>::value, U&>::type
		operator * () const { return *m_ptr; };
};

int main()
{
	int i = 12345;
	ptr<int> ptr_i(&i);
	std::cout << *ptr_i; // OK

	ptr<void> ptr_i2(&i);
	std::cout << *ptr_i2; // ERROR
	
	return 0;
}