これは、テンプレートではありませんが、offsetofマクロを用いるのが定石です。offsetofマクロは<cstddef>ヘッダで定義されますので、(組み込み用などの)自立処理系であっても、必ず提供されることが規格上保証されています(非標準処理系は別ですが)。
仮に、offsetofマクロを自作する必要がある場合、C言語では、
| 0 1 2 | #define offsetof(type, member) ((size_t)&((type*)0)->member) | 
とすれば十分でしたが、C++ではそうはいきません。なぜなら、&演算子が多重定義されている可能性があるからで、正しく動作させるためには、
| 0 1 2 3 4 5 | #define offset_of(type, member)  \     (reinterpret_cast<std::size_t>(  \       &reinterpret_cast<char const volatile&>(  \         ((type*)0)->member))) | 
とする必要があります。
ところで、ここは「C++関数・テンプレート集」であってマクロ集ではないので、やや強引ですが、テンプレート版も作ってみましょう。
| 0 1 2 3 4 5 6 7 8 | template<class T, class C> std::size_t offset_of(T (C::*pm)) {   return reinterpret_cast<std::size_t>(           &reinterpret_cast<const volatile char&>(((C*)0)->*pm)          ); } | 
引数としてメンバへのポインタを渡すことで、オフセットを返すoffset_of関数テンプレートです。定数式に展開することができないので、offsetofマクロにはどうしても劣りますが、テンプレートの中であれば、利用価値があるかもしれません。
なお、C++11以降であればstd::addressof関数が使えますので、次のように書いてもよいでしょう。
| 0 1 2 3 4 5 6 | template<class T, class C> std::size_t offset_of(T (C::*pm)) {   return (std::size_t)std::addressof(((C*)0)->*pm); } | 
std::addressof関数を使うには<memory>をインクルードしてください。






