#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;
}
I2luY2x1ZGUgPGlvc3RyZWFtPgoKdGVtcGxhdGU8dHlwZW5hbWUgVCwgdHlwZW5hbWUgRj4Kc2l6ZV90IGRvX3NvbWV0aGluZ19pbXBsKGNvbnN0IFQmIGEsIEYmIGYpCnsKICAgVCBpbnRlcm5hbF92YWx1ZShhKTsKICAgY29uc3QgVCYgY19pdiA9IGludGVybmFsX3ZhbHVlOwogICAvLyBkbyBzb21lIGNvbXBsaWNhdGVkIHRoaW5ncwogICAvLyBsb29wIHsKICAgLy8gICBsb29wIHsKICAgICAgIGYoY19pdik7CiAgICAgICAvLyBkbyBzb21lIG1vcmUgdGhpbmdzCiAgIC8vICAgfQogICAvLyB9CiAgIHJldHVybiA0MjsKfQoKdGVtcGxhdGU8dHlwZW5hbWUgVCwgdHlwZW5hbWUgRj4Kc2l6ZV90IGRvX3NvbWV0aGluZyhjb25zdCBUJiBhLCBGJiBmKQp7CiAgIHJldHVybiBkb19zb21ldGhpbmdfaW1wbDxULEY+KGEsIGYpOwp9Cgp0ZW1wbGF0ZTx0eXBlbmFtZSBULCB0eXBlbmFtZSBGPgpzaXplX3QgZG9fc29tZXRoaW5nKGNvbnN0IFQmIGEsIGNvbnN0IEYmIGYpCnsKICAgcmV0dXJuIGRvX3NvbWV0aGluZ19pbXBsPFQsY29uc3QgRj4oYSwgZik7Cn0KCnN0cnVjdCBDb25zdENhbGxhYmxlCnsKCXRlbXBsYXRlPHR5cGVuYW1lIFQ+IHZvaWQgb3BlcmF0b3IoKShjb25zdCBUJikgY29uc3Qge30KfTsKCnN0cnVjdCBOb3RDb25zdENhbGxhYmxlCnsKCWludCBpOwoJdGVtcGxhdGU8dHlwZW5hbWUgVD4gdm9pZCBvcGVyYXRvcigpKGNvbnN0IFQmKSB7ICsraTsgfQp9OwoKaW50IG1haW4oKQp7Cgljb25zdCBDb25zdENhbGxhYmxlIGY7CglOb3RDb25zdENhbGxhYmxlIGc7Cglkb3VibGUgbiA9IDMuMTQxNTk7Cglkb19zb21ldGhpbmcobiwgZik7Cglkb19zb21ldGhpbmcobiwgQ29uc3RDYWxsYWJsZSgpKTsKCWRvX3NvbWV0aGluZyhuLCBnKTsKCXJldHVybiAwOwp9