Saturday, November 30, 2013

taker


#include <iostream>
#include <iomanip>
//#include <sstream>
//#include <string>
//#include <vector>

using namespace std;

class ABC {
public:
    ABC() {
    }

    void operator()(int a) {
        cout << "a is  " << a << endl;
    }

    void set(const int& a) {
        this->a = a;
    }

    void set2(const int& b) {
        this->b = b;
    }

    static int get_sta() {
        return 10;
    }

    int& get()
    {
        return a;
    }

    int& get2()
    {
        return b;
    }

private:
    int a;
    int b;
};

template<typename R, typename C>
class taker {
public:
    typedef void (C::*SetFuncType)(const R&);
    typedef R& (C::*GetFuncType)();

    taker(C& anAssignee, SetFuncType aSetFunction, GetFuncType aGetFunction) :
        theAssignee(anAssignee), theSetFunction(aSetFunction),
                theGetFunction(aGetFunction) {
    }

    // use = to set its value.
    taker<R, C>& operator=(R aValue) {
        (theAssignee.*theSetFunction)(aValue);
        return *this;
    }

    // implicitly cast object to Return type : R
    operator R() const {
        return (theAssignee.*theGetFunction)();
    }

private:
    C& theAssignee;
    SetFuncType theSetFunction;
    GetFuncType theGetFunction;
};

// exposer : it can return a reference to object taken in from constructor.
template<typename R, typename C>
class exposer
{
public:
    typedef void (C::*SetFuncType)(const R&);
    typedef R& (C::*GetFuncType)();

    exposer(C& anObject, SetFuncType aSetFunction, GetFuncType aGetFunction) :
        theAssignee(anObject), theSetFunction(aSetFunction),
                theGetFunction(aGetFunction)
    {
    }

    // Return a reference to the object taken in from constructor,
    // That's why I call it exposer.
    C& me()  
    {
        return theAssignee;
    }

    R& getValue()
    {
        return (theAssignee.*theGetFunction)();
    }

    void giveMeGet(GetFuncType aGetFunction)
    {
        theGetFunction = aGetFunction;
    }

private:
    C& theAssignee;
    SetFuncType theSetFunction;
    GetFuncType theGetFunction;

};

// send non-static member function to f()
void f(ABC& a, int& (ABC::*getFunc)()) {
    cout << (a.*getFunc)() << endl;
}

// send non-static member function to f_gen() : generic
template<typename R, typename C>
void f_gen(C& a, R& (C::*getFunc)()) {
    cout << (a.*getFunc)() << endl;
}

// send static member function to f()
void f_sta(int(*pmf)()) {
    cout << (*pmf)() << endl;
}

int main() {

    cout << "-------------"  << endl;

    ABC abc1;
    f(abc1, &ABC::get);
    f_gen(abc1, &ABC::get);
    f_sta(&ABC::get_sta);

    taker<int, ABC> tt(abc1, &ABC::set, &ABC::get);
    tt=100;
    cout << (int)tt << endl;

    exposer<int, ABC> exp(abc1, &ABC::set, &ABC::get);
    ABC& abc2 = exp.me();
    abc2.set(22);
    cout << abc2.get() << endl;
    cout << exp.getValue() << endl;

    exp.giveMeGet(&ABC::get2);
    abc2.set2(111);
    cout << exp.getValue() << endl;


    return 0;
}


No comments:

Post a Comment