template<class T, typename U> ptrdiff_t foo(T U::* m)
{
// return offset
}
如何在此上下文中獲得字段'm'的偏移量?我寧願使用編譯時表達式。指向成員的偏移量
在此先感謝您的幫助。此致敬禮
template<class T, typename U> ptrdiff_t foo(T U::* m)
{
// return offset
}
如何在此上下文中獲得字段'm'的偏移量?我寧願使用編譯時表達式。指向成員的偏移量
在此先感謝您的幫助。此致敬禮
聽起來像你正在尋找offsetof()宏。
使用成員指針調用'offsetof',只有成員名是不合法的。 (在許多實現中它可能工作,但給出了這種事情的模糊程度,它可能會破壞任何編譯器更新) – Yakk 2014-03-09 17:00:38
Hi @Yakk。我不太清楚你的意思。如果你點擊「offsetof」(上面)這個詞,它將把你帶到宏的文檔。它對我來說看起來很潔淨。通過一個「成員指針」來指您是一個指針結構的成員?例如struct s {int i; char * p; }; size_t n = offsetof(struct s,p); – 2014-03-09 18:10:36
@Michael J
感謝您的回答。這不正是我一直在尋找,但它給了我靈感,這樣做:
template<class T, typename U>
std::ptrdiff_t member_offset(U T::* member)
{
return reinterpret_cast<std::ptrdiff_t>(
&(reinterpret_cast<T const volatile*>(NULL)->*member)
);
}
你在這裏是一個空指針的dereferensing。這是不允許的,除非你正在實現這個庫,並在offsetof宏中使用一個特殊的配置。有人打我到-1。 – 2011-04-11 07:16:22
這就是宏的offsetof:(size_t)&reinterpret_cast
區別在於offsetof對** particual編譯器**是這樣做的,只是因爲庫設計器與編譯器編寫器做了特殊處理。那麼它可能工作。在其他編譯器中,offsetof用作特殊的__builtin_offsetof函數。或者其他一些技巧。在庫中有一個offsetof的主要原因是你不能輕易地編寫它,你需要編譯器的特別支持。 – 2011-04-11 11:16:30
簡單的答案是,你不能。如果類型U是POD, 可以使用宏offsetof
,但在形式上,它是未定義的 行爲如果類型不是POD:取決於編譯器, 您將得到編譯時錯誤,或者完全錯誤結果一些 的時候。而且你不能在指向成員的指針上使用它。你 必須調用它與類的名稱,並且成員的名稱 。
這可能是一個壞主意。爲什麼不使用指向成員類型的指針? – GManNickG 2011-04-11 06:40:39
嗯,你究竟是什麼意思?上面的參數是一個指向成員的指針... – 0xbadf00d 2011-04-12 06:32:01
正確,並且保留它。偏移量太簡單,不適用於大多數C++類(非POD)。 – GManNickG 2011-04-12 06:47:22