#include <iostream>
#include <stdexcept>
 #include <typeinfo>
 
class Committer
{
public:	
 
	template <typename T>
	void mark_var_change(T *var)
	{
	    mPointer = var;
	    mTypeInfo = &typeid(T*);
	}
 
	template <typename T>
	void commit_change(T new_value)
	{
		if (*mTypeInfo != typeid(T*)) {
		    throw std::runtime_error("Bad type");
		}
		if (mPointer == nullptr) {
			throw std::runtime_error("nullptr was stocked");
		}
	    *reinterpret_cast<T*>(mPointer) = new_value;
	}
 
private:
    void* mPointer = nullptr;
    const std::type_info* mTypeInfo = nullptr;
};
 
 
int main() {
	Committer c;
	int i;
	float f;
 
	c.mark_var_change(&i);
	c.commit_change(42);
 
	c.mark_var_change(&f);
	c.commit_change(4.2f);
 
	std::cout << i << " " << f << std::endl;
	
	try
	{
		c.mark_var_change(&i);	
		c.commit_change(4.2f);	
	}
	catch (const std::exception&e)
	{
		std::cout << e.what() << std::endl;
	}
}

