Здравствуйте, rg45, Вы писали:
R>Такое "оно" у нас и так есть.
Да ладно?
#include <cstddef>
#include <iostream>
struct A {
int a,a1;
virtual ~A() {}
};
struct B : virtual A { int b; virtual void f1() {} };
struct C : virtual A { int c; virtual void f2() {} };
struct D : B,C { int d; };
#define myoffset(member) template<typename T> size_t offset_of_##member(const T& temp) { return (size_t)((char*)(&(temp.member)) - (char*)&temp); }
myoffset(d)
template<typename> struct struct_member_types;
template<typename T, typename F> struct struct_member_types<F T::*> {
using struct_type = T;
using member_type = F;
};
template<typename T> using struct_type_t = typename struct_member_types<T>::struct_type;
template<typename T> using member_type_t = typename struct_member_types<T>::member_type;
template<auto field> struct constexpr_field_offset {
using T = struct_type_t<decltype(field)>;
using F = member_type_t<decltype(field)>;
static constexpr const char const_holder = 0;
static constexpr const T& const_value = reinterpret_cast<const T&>(const_holder);
static constexpr const F T::* const_field = field;
static constexpr const char* base_addr = &reinterpret_cast<char const&>(const_value);
static constexpr const char* field_addr = &reinterpret_cast<char const&>(const_value.*const_field);
static constexpr const size_t offset = field_addr - base_addr;
};
template<auto field> inline constexpr std::size_t offset_of = constexpr_field_offset<field>::offset;
int main(int argc, char **argv) {
enum { c1=offset_of<&D::d> }; // это "оно" constexpr
//enum { c2=offset_of_d(D{}) }; // а это "оно" не constexpr
int v2=offset_of_d(D{});
std::cout<< c1 << " " << v2 << std::endl;
return 0;
}
28 28