#include <iostream>

template<typename T, typename F>
size_t do_something_impl(const T& a, F& f)
{
   T internal_value(a);
   const T& c_iv = internal_value;
   // do some complicated things
   // loop {
   //   loop {
       f(c_iv);
       // do some more things
   //   }
   // }
   return 42;
}

template<typename T, typename F>
size_t do_something(const T& a, F& f)
{
   return do_something_impl<T,F>(a, f);
}

template<typename T, typename F>
size_t do_something(const T& a, const F& f)
{
   return do_something_impl<T,const F>(a, f);
}

struct ConstCallable
{
	template<typename T> void operator()(const T&) const {}
};

struct NotConstCallable
{
	int i;
	template<typename T> void operator()(const T&) { ++i; }
};

int main()
{
	const ConstCallable f;
	NotConstCallable g;
	double n = 3.14159;
	do_something(n, f);
	do_something(n, ConstCallable());
	do_something(n, g);
	return 0;
}