#include <iostream>
using namespace std;
template <typename T>
struct NonConst {typedef T type;};
template <typename T>
struct NonConst<T const> {typedef T type;}; //by value
template <typename T>
struct NonConst<T const&> {typedef T& type;}; //by reference
template <typename T>
struct NonConst<T const*> {typedef T* type;}; //by pointer
template <typename T>
struct NonConst<T const&&> {typedef T&& type;}; //by rvalue-reference
template<typename TConstReturn, class TObj, typename... TArgs>
typename NonConst<TConstReturn>::type likeConstVersion(
TObj const* obj,
TConstReturn (TObj::* memFun)(TArgs...) const,
TArgs... args) {
return const_cast<typename NonConst<TConstReturn>::type>(
(obj->*memFun)(args...));
}
struct T {
int arr[100];
int const& getElement(size_t i) const{
return arr[i];
}
int& getElement(size_t i) {
return likeConstVersion(this, &T::getElement, i);
}
/*
int const& getElement() const{
return 42;
}
int& getElement() {
return likeConstVersion(this, &T::getElement);
}*/
};
int main() {
T t;
int b=t.getElement(4);
return 0;
}
I2luY2x1ZGUgPGlvc3RyZWFtPgp1c2luZyBuYW1lc3BhY2Ugc3RkOwoKCnRlbXBsYXRlIDx0eXBlbmFtZSBUPgpzdHJ1Y3QgTm9uQ29uc3Qge3R5cGVkZWYgVCB0eXBlO307CnRlbXBsYXRlIDx0eXBlbmFtZSBUPgpzdHJ1Y3QgTm9uQ29uc3Q8VCBjb25zdD4ge3R5cGVkZWYgVCB0eXBlO307IC8vYnkgdmFsdWUKdGVtcGxhdGUgPHR5cGVuYW1lIFQ+CnN0cnVjdCBOb25Db25zdDxUIGNvbnN0Jj4ge3R5cGVkZWYgVCYgdHlwZTt9OyAvL2J5IHJlZmVyZW5jZQp0ZW1wbGF0ZSA8dHlwZW5hbWUgVD4Kc3RydWN0IE5vbkNvbnN0PFQgY29uc3QqPiB7dHlwZWRlZiBUKiB0eXBlO307IC8vYnkgcG9pbnRlcgp0ZW1wbGF0ZSA8dHlwZW5hbWUgVD4Kc3RydWN0IE5vbkNvbnN0PFQgY29uc3QmJj4ge3R5cGVkZWYgVCYmIHR5cGU7fTsgLy9ieSBydmFsdWUtcmVmZXJlbmNlCgp0ZW1wbGF0ZTx0eXBlbmFtZSBUQ29uc3RSZXR1cm4sIGNsYXNzIFRPYmosIHR5cGVuYW1lLi4uIFRBcmdzPgp0eXBlbmFtZSBOb25Db25zdDxUQ29uc3RSZXR1cm4+Ojp0eXBlIGxpa2VDb25zdFZlcnNpb24oCiAgIFRPYmogY29uc3QqIG9iaiwKICAgVENvbnN0UmV0dXJuIChUT2JqOjoqIG1lbUZ1bikoVEFyZ3MuLi4pIGNvbnN0LAogICBUQXJncy4uLiBhcmdzKSB7CiAgICAgIHJldHVybiBjb25zdF9jYXN0PHR5cGVuYW1lIE5vbkNvbnN0PFRDb25zdFJldHVybj46OnR5cGU+KAogICAgICAgICAob2JqLT4qbWVtRnVuKShhcmdzLi4uKSk7Cn0KCnN0cnVjdCBUIHsKICAgaW50IGFyclsxMDBdOwogICBpbnQgY29uc3QmIGdldEVsZW1lbnQoc2l6ZV90IGkpIGNvbnN0ewogICAgICByZXR1cm4gYXJyW2ldOwogICB9CiAgIGludCYgZ2V0RWxlbWVudChzaXplX3QgaSkgewogICAgICByZXR1cm4gbGlrZUNvbnN0VmVyc2lvbih0aGlzLCAmVDo6Z2V0RWxlbWVudCwgaSk7CiAgIH0KICAgLyoKICAgaW50IGNvbnN0JiBnZXRFbGVtZW50KCkgY29uc3R7CiAgICAgIHJldHVybiA0MjsKICAgfQogICBpbnQmIGdldEVsZW1lbnQoKSB7CiAgICAgIHJldHVybiBsaWtlQ29uc3RWZXJzaW9uKHRoaXMsICZUOjpnZXRFbGVtZW50KTsKICAgfSovCn07CgppbnQgbWFpbigpIHsKCVQgdDsgIAoJaW50IGI9dC5nZXRFbGVtZW50KDQpOwoJcmV0dXJuIDA7Cn0=