Skip to content

Instantly share code, notes, and snippets.

@godfat
Created June 15, 2009 14:04
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save godfat/130125 to your computer and use it in GitHub Desktop.
Save godfat/130125 to your computer and use it in GitHub Desktop.
// author:
// http://joshkos.blogspot.com/2009/06/blog-post_13.html
#ifndef GETSET_HPP
#define GETSET_HPP
template<typename T, typename C, T C::* P>
struct Selector { // used for selecting which field to access
static T C::* const MP;
typedef T Type;
};
template<typename T, typename C, T C::* P>
T C::* const Selector<T, C, P>::MP = P;
template<typename Derived> // Curiously Recurring Template Pattern
class GetSet { // ref. <<C++ Templates: the Complete Guide>>,
// <<C++ Template Metaprogramming>>
public:
template<typename S>
const typename S::Type& get() const {
return static_cast<const Derived* const>(this)->*S::MP;
}
template<typename S>
void set(const typename S::Type& value){
static_cast<Derived* const>(this)->*S::MP = value;
}
};
// make defining selectors easier
#define GENERATE_SELECTOR(C,T,P,N) typedef Selector< T , C , & C :: P > N
#endif
// godfat ~/p/t/josh> g++-mp-4.4 -std=c++98 -Wall -pedantic test.cpp -o test
// godfat ~/p/t/josh> ./test
// hack
// 0
// hack
// 2
#include "getset.hpp"
#include <iostream>
using std::cout;
using std::endl;
class C: public GetSet<C>{
public:
template <typename S>
typename S::type const& get() const;
// protected:
int test;
};
GENERATE_SELECTOR(C, int, C::test, N);
template <typename S>
typename S::type const& C::get() const{
cout << "hack" << endl;
return GetSet<C>::get<N>();
}
int main(){
C c;
c.set<N>(0);
cout << c.get<N>() << endl;
c.set<N>(2);
cout << c.get<N>() << endl;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment