Ho la necessità di utilizzare offsetof
da un template
con un selettore membro. Mi è venuta in mente un modo, se volete scusarmi la sintassi imbarazzante:C++ Compile-Time offsetof all'interno di un modello
template <typename T,
typename R,
R T::*M
>
constexpr std::size_t offset_of()
{
return reinterpret_cast<std::size_t>(&(((T*)0)->*M));
};
uso non è perfetto (fastidioso nella migliore delle ipotesi):
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), "");
Il constexpr
forma non è più facile da usare:
template <typename T, typename R>
std::size_t offset_of(R T::*M)
{
return reinterpret_cast<std::size_t>(&(((T*)0)->*M));
};
allo svantaggio ovvio che non è fatto a tempo di compilazione (ma più facile da usare):
int main()
{
std::cout << offset_of(&S::x) << std::endl;
std::cout << offset_of(&S::y) << std::endl;
}
Quello che sto cercando è la sintassi come la varietà non constexpr
, ma ancora completamente in fase di compilazione; tuttavia, non riesco a trovare la sintassi per questo. Sarei anche contento di un offset_of<&S::x>::value
(come il resto dei tratti del tipo), ma non riesco a capire la magia della sintassi per questo.
Sto cercando di capire dove nello standard si dice che questo fa quello che ti aspetti che faccia. Ma non riesco a trovarlo. –
Cosa c'è di sbagliato con lo standard ['offsetof'] (http://en.cppreference.com/w/cpp/types/offsetof)? –
@NicolBolas Immagino che non sia così. Non dovrebbe esserci già UB il dereferenziamento di un 'nullptr' (e penso che' -> 'valga come dereferenziazione)? Ma poi di nuovo, la versione di VC della macro 'offsetof' non è diversa. Quindi in pratica è probabilmente l'implementazione definita piuttosto che non definita. –