template<class T, typename U> ptrdiff_t foo(T U::* m)
{
// return offset
}
このコンテキストでフィールド「m」のオフセットを取得するにはどうすればよいですか?amコンパイル時式を使用したいと思います。
助けてくれてありがとう。よろしくお願いします
template<class T, typename U> ptrdiff_t foo(T U::* m)
{
// return offset
}
このコンテキストでフィールド「m」のオフセットを取得するにはどうすればよいですか?amコンパイル時式を使用したいと思います。
助けてくれてありがとう。よろしくお願いします
@マイケル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)
);
}
offsetof()マクロを探しているようです。
簡単な答えはあなたができないということです。タイプUがPODの場合、マクロを使用できますがoffsetof
、正式には、タイプがPODでない場合は未定義の動作です。コンパイラによっては、コンパイル時エラーが発生するか、単に間違った結果が発生する場合があります。時間。また、メンバーへのポインタには使用できません。クラスの名前とメンバーの名前を使用して呼び出す必要があります。
オフセットを取得することはできますが、無料ではありません。
template <typename T, class C>
size_t memberOffset(T C::*member)
{
C c {};
return size_t(&(c.*member)) - size_t(&c);
}
// usage
struct Vector {
int x;
int y;
};
size_t off = memberOffset(&Vector::y);
残念ながら、ご覧のとおり、これはではないためconstexpr
、必要なすべてのシナリオで使用できるわけではありません。また、(非常に小さな)オーバーヘッドもありますが、コンパイラーが完全に最適化したようです:https ://godbolt.org/z/jGeox9 。
constexpr
自分でどこにでも振りかけてこれを機能させることができるかどうか疑問に思っている場合は、それをコンパイルして実行することもできますが、多くのコンパイラで許可されている既知の欠陥にもかかわらず、キャストtoの使用size_t
は無効です。constexpr
このメソッドのクレジットは私のものではなく、Daniel Weilerとこの優れた要点に帰属します:https ://gist.github.com/graphitemaster/494f21190bb2c63c5516