動的に型サイズを求めるスマポ
http://d.hatena.ne.jp/okzk/20060622#1150958620
から。動的にサイズを調べるのは以下のようなコードはどうでしょうか。先に言っておくと冗談です。 GCC と cl.exe で確認。たぶんきっと他でもだいたい動きますおそらく。
template<class T> class smart_ptr { T* p_; int size_; static int size_of(void* vp) { char* p = (char*)vp; void* vt = *(void**)p; for (p++; vt != *(void**)p; p++); return p-(char*)vp; } public: explicit smart_ptr(T* p) : p_(p) { #if 0 // 落ちる size_ = sizeof(T); #else // 問題なし size_ = size_of(p); #endif } T& operator[](int i) { return *(T*)((char*)p_+size_); } }; #include <iostream> using namespace std; class Base { public: virtual int get_val() {return 0;} virtual ~Base(){} }; class Derived : public Base { int dmy; public: virtual int get_val() {return 1;} virtual ~Derived(){} }; void print_val(Base* base, int size) { smart_ptr<Base> p(base); for (int i = 0; i < size; ++i) cout << p[i].get_val() << endl; } int main() { Base base[2]; print_val(base, 2); Derived derived[4]; print_val(derived, 4); return 0; }
仮定している内容は以下のこと。
- 仮想関数の無いクラスはたぶん使えない。
- smart_ptr のコンストラクタに渡したポインタは全て同じ型。
- 仮想関数テーブルがクラスの先頭にある。
- 配列サイズは2以上。
一個目の制限は、仮想関数のあるクラスか無いクラスか、は判定できる気がする…ので、解除できる気がしますが、ただのネタですし、なんかしんどいので省略。あと、テストとかいい加減なので間違ってるかも。