在非活动联合成员上使用“std::addressof”是否定义明确[重复]

2024-05-20

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

这取决于申请std::addressof工会非活跃成员的成员。

这是明确定义的 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 https://wandbox.org/permlink/rKQXopsltQ51VtEm

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


union U { int a; int b; };
U u;
u.a = 0; // (1)
int* pub = &u.b;

Yes, this is well defined, but there is restrictions on the way one can use pub. Note : taking the address of an object with the operator & or with std::addressof is similar1 unless a custom operator & is defined for that object's type.

[class.union]/1 http://eel.is/c%2B%2Bdraft/basic.life#6.sentence-1
在联合中,如果非静态数据成员的名称引用其生命周期已开始且尚未结束的对象,则该非静态数据成员处于活动状态。

所以在线标记(1), 的寿命u.b尚未启动,但对象将占用的存储空间已分配。下列的 :

[basic.life]/6 http://eel.is/c%2B%2Bdraft/basic.life#6.sentence-1
在对象的生命周期开始之前,但在该对象将占用的存储空间已分配之后,或者在对象的生命周期结束之后,在重用或释放该对象所占用的存储空间之前,任何表示该对象的地址的指针可以使用该对象将要或曾经位于的存储位置,但只能以有限的方式使用。


1) Except it would, as user Quentin noted, bind a reference to u.b, but it's also OK as per [basic.life]/7 http://eel.is/c%2B%2Bdraft/basic.life#7.sentence-1:

类似地,在对象的生命周期开始之前但在分配该对象将占用的存储空间之后,或者在对象的生命周期结束之后并且在重用或释放该对象占用的存储空间之前,引用的任何泛左值原始对象可以被使用,但只能以有限的方式使用。对于正在建设或销毁的对象,请参阅[class.cdtor]。否则,这样的左值引用分配的存储([basic.stc.dynamic.allocation]),并且使用不依赖于其值的左值的属性是明确定义的。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

在非活动联合成员上使用“std::addressof”是否定义明确[重复] 的相关文章

随机推荐

  • AdMob 收入是如何计算的? [关闭]

    Closed 这个问题不符合堆栈溢出指南 help closed questions 目前不接受答案 我对 AdMob 收入的计算方式有点困惑 我想使用以下屏幕截图作为示例 我有一些问题 每次点击费用是如何计算的 因为在这个例子中它是 1
  • select 语句是否保证通道选择的顺序?

    继从这个答案 https stackoverflow com a 25795236 274460 如果一个 goroutine 在两个通道上进行选择 是否保证通道的选择顺序与其发送的顺序相同 我对发送者是单线程的情况特别感兴趣 例如 是否保
  • 如何将 WPF 大小转换为物理像素?

    将 WPF 与分辨率无关 宽度和高度转换为物理屏幕像素的最佳方法是什么 我正在 WinForms 表单中显示 WPF 内容 通过 ElementHost 并尝试制定一些大小调整逻辑 当操作系统以默认 96 dpi 运行时 我可以正常工作 但
  • ASP.NET C# 中的自定义控件

    我创建了一个简单的自定义控件 它仅继承自Literal控件 并且还没有任何扩展 代码为空 命名空间 CustomControls 类名 文字 System Web UI WebControls Literal 接下来我要做的就是在aspx页
  • Qt 创建布局并动态添加小部件到布局

    我正在尝试在 MainWindow 类中动态创建布局 我有四个框架 它们是用网格布局对象放置的 每个框架都包含一个自定义的 ClockWidget 我希望 ClockWidget 对象在调整主窗口大小时相应地调整大小 因此我需要将它们添加到
  • 将数据打印到文件

    我已经超载了 lt lt 运算符 使其写入文件并写入控制台 我已经为同一个函数创建了 8 个线程 并且我想输出 hello hi 如果我在无限循环中运行这个线程例程 文件中的o p是 hello hi hello hi hello hi e
  • Windows10上打开/创建内网Vagrant失败

    我昨天将 Windows 10 升级到了最新更新 现在启动时vagrant up命令 我收到此错误 gt default Booting VM gt default Waiting for machine to boot This may
  • JQuery 验证在 IE8 中不起作用

    我使用 JQuery 验证脚本来验证 HTML 表单 这在 Firefox 中完美运行 但在 IE8 中不起作用 我认为冒号 或分号 有问题 但我无法抓住它 jQuery validator addMethod selectNone fun
  • 部分共享git仓库

    我是 git 新手 我想知道是否支持以下场景 如果支持的话如何支持 即用于设置和更新的 git 命令 可以从三个不同的地方获取存储库 本地 镜像 和 github mirror 完全镜像 local github 镜像 local 但 受版
  • android httprequest java.net.UnknownHostException

    我想用android发出http请求 是使用这个 void testHTTP HttpClient httpClient new DefaultHttpClient HttpUriRequest request new HttpPost h
  • 我可以在 PHP 会话变量中安全地存储用户名和密码吗?

    我想在 REST api 之上制作一个轻量级的 web 应用程序 用户只需进行一次身份验证 从那时起 所有针对 web api 的请求都希望通过以某种方式保持用户名和密码有效来完成 我已经做了一个工作原型我在哪里将用户名和密码存储在会话变量
  • 如何使用非标准的一周第一天在 Oracle 中计算一年中的第几周?

    我有一个查询需要返回日期字段的 一年中的第几周 但查询的客户使用非标准的一周第一天 所以TO CHAR with IW 没有返回预期的结果 在这种情况下 一周的第一天是周六 周五是一周的第七天 对于 T SQL 我会使用DATEPART a
  • Linux 上有关 getBounds() 和 setBounds() 的 bug_id=4806603 的解决方法?

    在 Linux 平台上 Frame getBounds 和 Frame setBounds 的工作方式不一致 这在 2003 年就已经有报道了 请参见此处 http bugs java com bugdatabase view bug do
  • 使用 Gas 生成与位置无关的代码 (-fPIC)

    我尝试在 x86 64 上创建共享库但失败 问题归结为以下代码 请不要介意 它没有多大意义 section data newline ascii n section text globl write newline type write n
  • 使用 .INTERMEDIATE 在 makefile 中进行不可靠的并行构建?

    我有一个可以生成多个输出文件的工具 众所周知 在 make 中很难建模 我正在使用食谱GNU Makefile 规则从单个源文件生成一些目标 https stackoverflow com questions 2973445 gnu mak
  • 对象锁定私有类成员 - 最佳实践? (爪哇)

    I asked 类似的问题 https stackoverflow com questions 10548066 multiple object locks in java前几天 但对回复不满意 主要是因为我提供的代码存在一些人们关注的问题
  • 淡出和循环一组 div 的最佳方式

    假设我有以下 div div class a You are funny div div class b You are smart div div class c You are cool div 最好的展示方式是什么div a持续 5
  • 从 TFS 2010 就地迁移到 TFS 2015

    我对从 Team Foundation Server 2010 就地升级到 Team Foundation Server 2015 有疑问 我们目前的情况包含以下软件版本 Windows Server 2008 R2 SQL Server
  • 将 USD 模型转换为 GLTF 文件格式 [关闭]

    Closed 这个问题需要多问focused help closed questions 目前不接受答案 我一直在寻找一种转换的方法 usdc usda usdz文件到 gltf使用命令行 Python 节点等等 到目前为止 一直在研究每个
  • 在非活动联合成员上使用“std::addressof”是否定义明确[重复]

    这个问题在这里已经有答案了 下面的代码是尝试实现constexpr的版本offsetof在 C 11 中 它可以在 gcc 7 2 0 和 clang 5 0 0 中编译 这取决于申请std addressof工会非活跃成员的成员 这是明确