5
template<class T, typename U> ptrdiff_t foo(T U::* m)
{
    // return offset
}

このコンテキストでフィールド「m」のオフセットを取得するにはどうすればよいですか?amコンパイル時式を使用したいと思います。

助けてくれてありがとう。よろしくお願いします

4

4 に答える 4

6

@マイケル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)
    );
}
于 2011-04-11T06:38:28.690 に答える
2

offsetof()マクロを探しているようです。

于 2011-04-11T06:18:27.910 に答える
0

簡単な答えはあなたができないということです。タイプUがPODの場合、マクロを使用できますがoffsetof、正式には、タイプがPODでない場合は未定義の動作です。コンパイラによっては、コンパイル時エラーが発生するか、単に間違った結果が発生する場合があります。時間。また、メンバーへのポインタには使用できません。クラスの名前とメンバーの名前を使用して呼び出す必要があります。

于 2011-04-11T08:47:07.113 に答える
0

オフセットを取得することはできますが、無料ではありません。

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

于 2021-02-09T06:52:20.040 に答える