2008年7月14日星期一

尼采的神奇 Functor

尼采給我的題目...不如在此發表答案.


#include <iostream>

typedef int (*Functor)();

// Recursive type template that generate a
// compile-time list of Functor using inheritance
template<size_t N> struct Unit : public Unit<N-1> {
Unit() : mFunctor(&Unit<N>::fun) {}
static int fun() { return N; }
Functor mFunctor;
};

// Partial specialization to end the recursion
template<> struct Unit<0> {
Unit() : mFunctor(&Unit<0>::fun) {}
static int fun() { return 0; }
Functor mFunctor;
};

// Partial specialization to reduce recursive template complexity
template<> struct Unit<256> : public Unit<255> {
Unit() : mFunctor(&Unit::fun) {}
static int fun() { return 256; }
Functor mFunctor;
};

// Partial specialization to reduce recursive template complexity
template<> struct Unit<512> : public Unit<511> {
Unit() : mFunctor(&Unit::fun) {}
static int fun() { return 512; }
Functor mFunctor;
};

// A compile-time maximum count of Functor
static const size_t cMaxN = 768;

typedef Unit<cMaxN> List;
static const List cList;

// A function that return a Functor that return i.
// In other words, it selects from a list of compile-time functors
// base on the run-time parameter i.
Functor getFunctor(int i) {
{ // We have the assumption that Unit<> struct are packed tightly together in cList
typedef const char* byte_ptr;
byte_ptr functorAddres1 = byte_ptr(&(static_cast<const Unit<1>*>(&cList)->mFunctor));
byte_ptr functorAddres2 = byte_ptr(&(static_cast<const Unit<2>*>(&cList)->mFunctor));
(void)functorAddres1; (void)functorAddres2;
assert(functorAddres2 - functorAddres1 == sizeof(Functor));
}
assert(i <= cMaxN);
return *((Functor*)(&cList) + i);
}

int main() {
for(size_t i=0; i<=cMaxN; ++i) {
Functor f = getFunctor(i);
std::cout << f() << std::endl;
assert(f() == int(i));
}

return 0;
}


Win少, 我的答案正確嗎?

2 則留言:

  1. 好利害....

    1), 可以recursive 1024 次嗎??

    回覆刪除
  2. VC2008 大概可遞歸 256 次, 因此給 256, 512 和 768 做特化可以了. 我証實了 1024 次會大概增加 40k binary code.

    回覆刪除