メンバーセレクタでtemplate
のoffsetof
を使用する必要があります。あなたは厄介な構文を失礼場合、私は、道を作ってみた:C++テンプレート内のコンパイル時のオフセット
template <typename T,
typename R,
R T::*M
>
constexpr std::size_t offset_of()
{
return reinterpret_cast<std::size_t>(&(((T*)0)->*M));
};
使用法(迷惑せいぜい)完璧ではありません。
struct S
{
int x;
int y;
};
static_assert(offset_of<S, int, &S::x>() == 0, "");
static_assert(offset_of<S, int, &S::y>() == sizeof(int), "");
非constexpr
フォームが簡単です使用する:
template <typename T, typename R>
std::size_t offset_of(R T::*M)
{
return reinterpret_cast<std::size_t>(&(((T*)0)->*M));
};
それはコンパイル時に行われていません(ただし、簡単に使用する)ことを明らかに不利な立場に:
int main()
{
std::cout << offset_of(&S::x) << std::endl;
std::cout << offset_of(&S::y) << std::endl;
}
私が探しているのは、のような構文ですが、constexpr
ではありませんが、まだ完全にコンパイルされています。しかし、私はそれのための構文を考え出すことはできません。私はoffset_of<&S::x>::value
(他のタイプの特徴と同様)にも満足していますが、そのための構文マジックを理解することはできません。 gccのでは、offsetof
マクロが(下記参照)、コンパイル時に使用することができ、組み込み拡張子に展開することを
#include <cstddef>
template <typename T, typename M> M get_member_type(M T::*);
template <typename T, typename M> T get_class_type(M T::*);
template <typename T,
typename R,
R T::*M
>
constexpr std::size_t offset_of()
{
return reinterpret_cast<std::size_t>(&(((T*)0)->*M));
}
#define OFFSET_OF(m) offset_of<decltype(get_class_type(m)), \
decltype(get_member_type(m)), m>()
struct S
{
int x;
int y;
};
static_assert(OFFSET_OF(&S::x) == 0, "");
注:
私は、標準で、これがあなたが期待していることをしていると言っているところを理解しようとしています。しかし、私はそれを見つけることができません。 –
標準の['offsetof'](http://en.cppreference.com/w/cpp/types/offsetof)には何の問題がありますか? –
@NicolBolas私はそうは思わない。 'nullptr'の逆参照ではないはずです(そして' - > 'は逆参照とみなされます)はすでにUBですか?しかし、やはり、VCの 'offsetof'マクロのバージョンはそれほど変わっていません。したがって、実際には、おそらく定義されていないよりもむしろ実装が定義されています。 –