Mam potrzebę użycia offsetof
z template
za pomocą selektora elementów. Mam wymyślić sposób, jeśli będziesz wybaczyć niezręczną składnię:C++ Przesunięcie czasu kompilacji wewnątrz szablonu
template <typename T,
typename R,
R T::*M
>
constexpr std::size_t offset_of()
{
return reinterpret_cast<std::size_t>(&(((T*)0)->*M));
};
Wykorzystanie nie jest doskonały (irytujące w najlepszym razie):
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), "");
Niezasychające constexpr
forma jest łatwiejsza używać:
template <typename T, typename R>
std::size_t offset_of(R T::*M)
{
return reinterpret_cast<std::size_t>(&(((T*)0)->*M));
};
z powodu oczywistej wady, że nie odbywa się w czasie kompilacji (lecz łatwiej wykorzystać)
int main()
{
std::cout << offset_of(&S::x) << std::endl;
std::cout << offset_of(&S::y) << std::endl;
}
Czego szukam, to składnia podobna do odmiany innej niż constexpr
, ale wciąż pełna kompilacja; jednak nie mogę wymyślić dla niego składni. Byłbym też zadowolony z offset_of<&S::x>::value
(podobnie jak pozostałe cechy typu), ale nie mogę znaleźć dla niego magii składni.
Próbuję dowiedzieć się, gdzie w standardzie, że mówi, że robi to, czego oczekujesz. Ale nie mogę tego znaleźć. –
Co jest nie tak ze standardem ["offsetof"] (http://en.cppreference.com/w/cpp/types/offsetof)? –
@NicolBolas Przypuszczam, że tak nie jest. Czy nie powinno być już wyodrębnianie "nullptr" (i myślę, że '->" liczy się jako dereferencja)? Ale znowu, wersja VC 'offof' makro nie jest inna. Tak więc w praktyce jest to prawdopodobnie raczej definicja zdefiniowana niż niezdefiniowana. –