gpt4 book ai didi

c++ - 在非事件联盟成员上使用 `std::addressof` 是否明确

转载 作者:太空狗 更新时间:2023-10-29 21:11:43 26 4
gpt4 key购买 nike

<分区>

下面的代码尝试在 C++11 中实现 offsetofconstexpr 版本。它在 gcc 7.2.0 和 clang 5.0.0 中编译。

这取决于将 std::addressof 应用于 union 体的非活跃成员的成员。

这是定义明确的 C++11 吗?如果不是,请解释原因,包括引用或引用标准的相关部分。

#include <iostream>
#include <cstdint>
#include <memory>

// based on the gist at: https://gist.github.com/graphitemaster/494f21190bb2c63c5516
// original version by graphitemaster

template <typename T1, typename T2>
struct offset_of_impl {
union U {
char c;
T1 m; // instance of type of member
T2 object;
constexpr U() : c(0) {} // make c the active member
};
static constexpr U u = {};

static constexpr std::ptrdiff_t offset(T1 T2::*member) {
// The following avoids use of reinterpret_cast, so is constexpr.
// The subtraction gives the correct offset because the union layout rules guarantee that all
// union members have the same starting address.
// On the other hand, it will break if object.*member is not aligned.
// Possible problem: it uses std::addressof on non-active union members.
// Please let us know at the gist if this is defined or undefined behavior.
return (std::addressof(offset_of_impl<T1, T2>::u.object.*member) -
std::addressof(offset_of_impl<T1, T2>::u.m)) * sizeof(T1);
}
};

template <typename T1, typename T2>
constexpr typename offset_of_impl<T1, T2>::U offset_of_impl<T1, T2>::u;

template <typename T1, typename T2>
inline constexpr std::ptrdiff_t offset_of(T1 T2::*member) {
return offset_of_impl<T1, T2>::offset(member);
}

struct S {
S(int a_, int b_, int c_) : a(a_), b(b_), c(c_) {}
S() = delete;
int a;
int b;
int c;
};

int main()
{
std::cout << offset_of(&S::b);
}

作为引用,这里有一个可以玩的沙盒版本:https://wandbox.org/permlink/rKQXopsltQ51VtEm

这是 graphitemaster 的原始版本: https://gist.github.com/graphitemaster/494f21190bb2c63c5516

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