#include <iostream>
#include <type_traits>
using namespace std;
/** Yet another concat implementation. */
#define YA_CAT_IMPL(x, y) x##y
/** Yet another concat. */
#define YA_CAT(x, y) YA_CAT_IMPL(x, y)
/**
* Init private class member hijacker.
* @param class_ Class name.
* @param member Private member to hijack.
* @param __VA_ARGS__ Member type.
*/
#define HIJACKER(class_, member, ...) \
namespace dirty_hacks { namespace hijack { \
template <class> struct tag_##member; \
inline auto get(tag_##member<class_>) -> __VA_ARGS__ class_::*; \
template <> struct tag_##member<class_> { \
tag_##member() {} \
template <class T, class = std::enable_if_t<std::is_base_of<class_, T>::value>> \
tag_##member(tag_##member<T>) {} \
}; \
template <__VA_ARGS__ class_::* Ptr> struct YA_CAT(hijack_##member##_, __LINE__) { \
friend auto get(tag_##member<class_>) -> __VA_ARGS__ class_::* { return Ptr; } \
}; \
template struct YA_CAT(hijack_##member##_, __LINE__)<&class_::member>; \
}}
/**
* Hijack private class member.
* @param ptr Pointer to class instance.
* @param member Private member to hijack.
*/
#define HIJACK(ptr, member) \
((ptr)->*dirty_hacks::hijack::get( \
dirty_hacks::hijack::tag_##member<std::remove_cv_t<std::remove_pointer_t<decltype(ptr)>>>() \
))
class TestClass
{
public:
TestClass() :val(1),str("Hello World"){}
const int & GetVal()const{ return val; }
const string & GetString()const{ return str; }
private:
int val;
string str;
};
HIJACKER(TestClass, val, int);
HIJACKER(TestClass, str, string);
int main(void)
{
TestClass d;
HIJACK(&d, val) = 233;
HIJACK(&d, str) = "Hello Beijing";
int i = d.GetVal();
string str = d.GetString();
return 0;
}