Re[9]: offsetof() без UB
От: kov_serg Россия  
Дата: 27.03.25 09:38
Оценка:
Здравствуйте, 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
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.