将 std::unique_ptr 保存为不完整类型的类的构造函数定义之间的差异

2024-03-26

下面的代码编译正常(参见下面的 Golbolt 链接):

#include <memory>

struct B;

struct A1 {
    A1() = default;
    ~A1();
    std::unique_ptr<B> ptr;
};

#if 0
struct A2 {
    A2();
    ~A2();
    std::unique_ptr<B> ptr;
};
A2::A2() = default;
#endif

int main()
{
}

但如果我更换#if 0 with #if 1编译类A2我从 gcc 收到以下错误:

In file included from /opt/compiler-explorer/gcc-12.2.0/include/c++/12.2.0/memory:76,
                 from <source>:1:
/opt/compiler-explorer/gcc-12.2.0/include/c++/12.2.0/bits/unique_ptr.h: In instantiation of 'void std::default_delete<_Tp>::operator()(_Tp*) const [with _Tp = B]':
/opt/compiler-explorer/gcc-12.2.0/include/c++/12.2.0/bits/unique_ptr.h:396:17:   required from 'std::unique_ptr<_Tp, _Dp>::~unique_ptr() [with _Tp = B; _Dp = std::default_delete<B>]'
<source>:17:1:   required from here
/opt/compiler-explorer/gcc-12.2.0/include/c++/12.2.0/bits/unique_ptr.h:93:23: error: invalid application of 'sizeof' to incomplete type 'B'
   93 |         static_assert(sizeof(_Tp)>0,
      |                       ^~~~~~~~~~~
ASM generation compiler returned: 1
In file included from /opt/compiler-explorer/gcc-12.2.0/include/c++/12.2.0/memory:76,
                 from <source>:1:
/opt/compiler-explorer/gcc-12.2.0/include/c++/12.2.0/bits/unique_ptr.h: In instantiation of 'void std::default_delete<_Tp>::operator()(_Tp*) const [with _Tp = B]':
/opt/compiler-explorer/gcc-12.2.0/include/c++/12.2.0/bits/unique_ptr.h:396:17:   required from 'std::unique_ptr<_Tp, _Dp>::~unique_ptr() [with _Tp = B; _Dp = std::default_delete<B>]'
<source>:17:1:   required from here
/opt/compiler-explorer/gcc-12.2.0/include/c++/12.2.0/bits/unique_ptr.h:93:23: error: invalid application of 'sizeof' to incomplete type 'B'
   93 |         static_assert(sizeof(_Tp)>0,
      |                       ^~~~~~~~~~~
Execution build compiler returned: 1

Godbolt https://godbolt.org/z/nGdE3qnov

我在 MSVC 上得到了类似的结果。
无论我编译为 C++17 还是 C++20,我都会得到这个结果。

我的问题:
之间唯一的区别A1 and A2是类定义内部或外部的构造函数的定义(在这两种情况下,它都定义为default).
为何本案有差异?

这个问题是这篇文章的后续问题:为什么 unique_ptr 需要构造函数中的完整类型? https://stackoverflow.com/questions/75408648/why-unique-ptr-requires-complete-type-in-constructor?noredirect=1#comment133056692_75408648.


区别如下:在A1,其中默认构造函数在其第一个声明中被默认,编译器在需要它的定义之前实际上不会定义它,并且因为在任何时候您都不会真正尝试创建一个A1object,此翻译单元中永远不需要默认构造函数的定义,因此编译器永远不会生成该定义。至于A2,越界定义

A2::A2() = default;

实际上为它出现的函数生成一个定义。在那时候,B必须是完整的,但事实并非如此。这在链接的问题中进行了解释。

See [dcl.fct.def.默认]/5 http://eel.is/c++draft/dcl.fct.def.default#5.sentence-6:

[...] 一个函数是用户提供的如果它是用户声明的并且在第一次声明时未明确默认或删除。 用户提供的显式默认函数(即在第一次声明后显式默认)在显式默认时隐式定义;如果这样的函数被隐式定义为已删除,则该程序是错误的。 未定义为删除的非用户提供的默认函数(即在类中隐式声明或显式默认)在使用 odr ([basic.def.odr]) 或需要常量求值 ([表达式.const])。

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

将 std::unique_ptr 保存为不完整类型的类的构造函数定义之间的差异 的相关文章

随机推荐

  • 单元测试通过 Django 中模型的正则表达式验证器

    我为 models py 中的一些字段定义了模型以及正则表达式验证器 在tests py中 我编写了测试来验证这些验证器 但它们却通过了 尽管当我尝试通过视图输入错误的值时验证器会发出警报 并且我的 forms py 中没有该表单的任何 干
  • 如何查询iPhone当前的IP地址?

    如何查询iPhone当前的IP地址 如果你想要externalIP地址 用于从本地网络外部连接的IP地址 您需要查询外部网络上的服务器 快速搜索后得到以下结果 http checkip dyndns org http checkip dyn
  • Edmx 需要 Primary_Key 吗?

    在 net 中创建 Edmx 时 在创建数据库的 Edmx 时 仅添加具有主键的表和视图 这是一个问题 这个问题很容易解决 但只需在表或视图中创建列主键 但我不知道为什么有必要 谁能解释一下其背后的原因吗 实体框架需要一个主键来正确地将一条
  • 在 node-cron 中获取下一个 cron 作业时间

    在node cron中 如何获取下一个cron作业的时间 例如cronJob next CronJob time 或其他属性 文档中没有任何方法可以证明这一点 我不知道有什么方法可以使用节点 cron https www npmjs com
  • Windows Azure 共享访问签名始终给出:Forbidden 403

    我正在尝试获取单个 blob 的共享访问签名 然后使用 REST api 下载该 blob 但是 我总是收到禁止的 403 错误消息 都在存储模拟器和云上 这是我的代码 CloudStorageAccount storageAccount
  • File.Copy 之后文件正被另一个进程使用

    我正在尝试管理我的网络应用程序中的文件 有时 我必须在文件夹中创建一个文件 使用 File Copy File Copy oldPath newPath 几秒钟后该文件可能会被删除 if File Exists newPath File D
  • GUID 或 GUID 的 SHA1 哈希之间发生冲突的可能性是否更大?

    之间发生碰撞的机会是否更大GUID s 128 位 或 SHA1 哈希值GUID s 160 位 我的观点是 机会较小GUID 即使少了 32 位 因为它有一些特殊的机制来确保它 几乎 因为没有保证 唯一 例如 时间戳 注意 我已经知道GU
  • 点击屋。在集群上创建数据库超时结束

    我有一个由 Clickhouse 的两个节点组成的集群 两个实例都位于 docker 容器中 主机之间的所有通信均已成功检查 ping telnet wget 工作正常 在 Zookeeper 中 我可以在下面看到我触发的查询ddl bru
  • Android Studio 3.2.1,XML 错误缩进格式

    更新到 Android Studio 3 2 1 后 XML 文件格式非常烦人和糟糕 我们该如何修复它 我们可以将其从设置中的某处更改为预览类型吗 在 Android Studio 3 上 转到 首选项 gt 编辑器 gt 代码样式 gt
  • Eclipse 中源的相对路径

    所以 Eclipse 和相对路径 我想要实现的是与多个用户共享项目文件 其中每个用户的源的确切位置可能不同 即 项目 MyProject 的 src 可能位于c version control foo MyProject src or c
  • 操作栏 sherlock 库中显示空指针异常

    我想实现 Sherlock 操作栏的搜索视图小部件 我的问题是OnOptionItemSelected搜索视图项目的 我在库活动中遇到空指针异常 菜单 XML
  • WPF 复选框绑定

    虽然使用复选框的 Click 事件将复选框的选中状态存储在变量中很简单 但我如何通过数据绑定来做到这一点 我发现的所有示例都从某个数据源更新了 UI 或者将一个控件绑定到另一个控件 我想在单击复选框时更新成员变量 TIA 的任何指示 您必须
  • Secure Com SCP02 会话:响应初始化更新命令返回的“密钥多样化数据”的作用是什么

    在初始化更新命令的响应字段中 密钥多样化数据 包含制造商ID和安全域AID的最后两个字节 被返回到Off Card实体 我想知道这些数据的用途是什么 我在某处读到 该密钥多样化数据用于派生卡外的基本密钥 我不知道这是对还是错 如果是正确的
  • 如何将 libxml2 与 CMake 一起使用?

    我正在为我的 C 项目使用 CLion 编辑器 带有 CMake 不过我从未使用过外部库 我的问题是如何将外部库 例如 libxml2 链接到我的项目 我见过一些与此类似的问题 但没有一个对我有用 我的项目是在 Windows 上编译的 我
  • 使用predict()函数时出错

    我应该将输出转换为ar ols成为某种类型predict可以接受吗 y rnorm 100 0 1 z rnorm 100 0 1 yz cbind y z gt output ar ols yz aic F order max 2 dem
  • GIT 命名我的存储库

    我正在跟进本指南 http progit org book ch4 2 html它说要跑的地方 git clone bare stef project stef project git I get fatal repository stef
  • linux下用boost::thread创建boost::asio工作线程

    我在 Windows 下使用 boost 一段时间了 现在需要迁移几个现有的应用程序以在 Ubuntu 12 上运行进行演示 该应用程序创建两个工作线程 一个用于记录传入的 UDP 数据 另一个用于侦听单独的端口并将该数据打印到屏幕上 我已
  • 有没有办法从 Excel VBA 中的轴导出图表?

    我有许多用于操作 Excel 图表的通用 VBA 宏 例如 将一个图表叠加在另一个图表之上 重新缩放轴 或者通过键入公式向图表添加自定义曲线 例如 y x 2 1 在文本框中 这些宏是不带任何参数的子宏 我将它们存储在 xlam 加载项中
  • 包含按位与 (&) 或按位异或 (^) 的运算是否有等价的十进制?

    考虑以下表达式 其中两个操作数都是十进制 a b or a b 我知道运算符对操作数的二进制数字执行什么操作 因此我知道答案如何 的a b or a b被计算 我不知道这些运算是否可以转换为十进制形式 例如 我们可以说a lt
  • 将 std::unique_ptr 保存为不完整类型的类的构造函数定义之间的差异

    下面的代码编译正常 参见下面的 Golbolt 链接 include