gpt4 book ai didi

c++ - constexpr Offsetof 带有指向成员数据的指针

转载 作者:行者123 更新时间:2023-12-04 11:15:31 28 4
gpt4 key购买 nike

就在这个问题因重复而被驳回之前,大多数(如果不是全部)问题都已接受答案,并带有过时/未定义的行为解决方案。

问题:

有没有办法在编译时获得指向成员数据的指针的偏移量:

  • 不依赖于未定义的行为(nullptr 事物)
  • 适用于最新的 gcc 版本(编译器资源管理器中的 gcc trunk)
  • offsetof 的工作方式相同(或类似地,就像提议的代码那样)。

  • 我不在乎:
  • 非标准布局类型
  • msvc 兼容性。 (它可能很好,但可选)
  • 对特定编译器有特殊情况

  • 问题:

    使用 GCC 的主干版本,以下技巧(hack)不起作用:
    #include <cstdint>
    #include <cstddef>

    namespace detail
    {
    // The union stuff is for CLang to avoid creating warnings
    template<typename T, auto MPtr>
    struct offsetof_ptr_helper
    {
    union helper_t { int i = 0; T value; };
    static constexpr helper_t v = {};
    static constexpr size_t sz = sizeof
    (uint8_t[
    (uint8_t *)&(v.value.*MPtr) -
    (uint8_t *)&v.value
    ]);
    };
    }

    template<typename T, auto MPtr>
    static constexpr size_t offsetof_ptr()
    {
    return detail::offsetofptr_helper<T, MPtr>::sz;
    }

    size_t f()
    {
    struct X { char c[10]; int a; };
    return offsetof_ptr<X, &X::a>();
    }

    需要明确的是,这是一个使用 C++98 特性的 hack,它的支持被最新的编译器删除并不令人意外。它适用于 clang(使用 -std=gnu++17 标志)和 gcc(包括/高达 g++ 7.3 使用标志 -std=c++17 )。

    最佳答案

    如果跳转到offsetof的定义在 VS 中,它为您提供:

    #define offsetof(s,m) ((::size_t)&reinterpret_cast<char const volatile&>((((s*)0)->m)))
    修改了一下以匹配您的问题:
    template<typename T, auto MPtr>
    static constexpr size_t offsetof_ptr()
    {
    return ((::size_t) & reinterpret_cast<char const volatile&>((((T*)0)->*MPtr)));
    }

    size_t f()
    {
    struct X { char c[10]; int a; };
    return offsetof_ptr<X, &X::a>();
    }
    这在 GCC 和 MSVC 上编译。 (由于模板自动参数,它需要 C++17。)

    关于c++ - constexpr Offsetof 带有指向成员数据的指针,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50080560/

    28 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com