调用基本构造函数时是否应该复制继承构造函数的参数?

2023-11-27

对于以下程序:

#include <iostream>

struct Foo
{
    Foo() { std::cout << "Foo()\n"; }
    Foo(const Foo&) { std::cout << "Foo(const Foo&)\n"; }
    ~Foo() { std::cout << "~Foo()\n"; }
};

struct A
{
    A(Foo) {}
};

struct B : A
{
    using A::A;
};

int main()
{
    Foo f;
    B b(f);
}

海湾合作委员会给出:

$ g++ -std=c++17 -O2 -Wall -pedantic -pthread main.cpp && ./a.out
Foo()
Foo(const Foo&)
~Foo()
~Foo()

VS 2017(也在 C++17 模式下)给出:

Foo()
Foo(const Foo&)
Foo(const Foo&)
~Foo()
~Foo()
~Foo()

谁是对的,为什么?

(我们也不要忘记 VS 2017 没有正确执行强制的复制省略。因此,可能只是副本是“真实的”,但 GCC 根据 C++17 规则删除了它,而 VS 则不然……)


Visual Studio 似乎没有实现P0136然而。正确的 C++17 行为是单个副本,原始 C++14 行为是两个副本。


C++14 规则 (N4140:[类.inhctor]) 会解释为:

struct B : A
{
    using A::A;
};

as:

struct B : A
{
    B(Foo f) : A(f) { }
};

引入的构造函数在 p3 中指定,mem 初始化器在 p8 中等效。因此你会得到两份副本Foo: 一入B的合成构造函数和一到A的真正构造函数。


由于 P0136,C++17 规则非常不同(N4659:[class.inhtor.init]): 在那里,我们直接调用A的构造函数。这并不是说我们要添加一个新的构造函数B不再是了——而且它不是一种可以用语言表达的机制。因为我们直接调用A(Foo),这只是一份副本而不是两份。

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

调用基本构造函数时是否应该复制继承构造函数的参数? 的相关文章

  • 捕获 .aspx 和 .ascx 页面中的异常

    问题说明了一切 请看以下示例代码 ul li li ul
  • 关于逻辑/算法的想法以及如何防止线程写入 Sql Server 中的竞争

    我有以下逻辑 public void InQueueTable DataTable Table int incomingRows Table Rows Count if incomingRows gt RowsThreshold async
  • Boost ASIO 串行写入十六进制值

    我正在使用 ubuntu 通过串行端口与设备进行通信 所有消息都必须是十六进制值 我已经在 Windows 环境中使用白蚁测试了通信设置 并得到了我期望的响应 但在使用 Boost asio 时我无法得到任何响应 以下是我设置串口的方法 b
  • 在 Mono 中反序列化 JSON 数据

    使用 Monodroid 时 是否有一种简单的方法可以将简单的 JSON 字符串反序列化为 NET 对象 System Json 只提供序列化 不提供反序列化 我尝试过的各种第三方库都会导致 Mono Monodroid 出现问题 谢谢 f
  • 用于在标头更改时重新编译的简单 C 项目的示例 makefile

    有谁有完整的 makefile 可以执行以下操作 如果 HEADER 文件发生更改 则重建项目 cpp 文件在 makefile 中列出 头文件未在 makefile 中列出 头文件允许与 cpp 文件具有不同的名称 部分cpp文件没有头文
  • Makefile 和 .Mak 文件 + CodeBlocks 和 VStudio

    我对整个 makefile 概念有点陌生 所以我对此有一些疑问 我正在 Linux 中使用 CodeBlocks 创建一个项目 我使用一个名为 cbp2mak 的工具从 CodeBlocks 项目创建一个 make 文件 如果有人知道更好的
  • C# 根据当前日期传递日期时间值

    我正在尝试根据 sql server 中的两个日期获取记录 Select from table where CreatedDate between StartDate and EndDate我通过了5 12 2010 and 5 12 20
  • Unity手游触摸动作不扎实

    我的代码中有一种 错误 我只是找不到它发生的原因以及如何修复它 我是统一的初学者 甚至是统一的手机游戏的初学者 我使用触摸让玩家从一侧移动到另一侧 但问题是我希望玩家在手指从一侧滑动到另一侧时能够平滑移动 但我的代码还会将玩家移动到您点击的
  • 来自嵌入图像的 BitmapSource

    我的目标是在 WPF 窗口上重写 OnRender 方法中绘制图像 someImage png 它是嵌入资源 protected override void OnRender System Windows Media DrawingCont
  • 条件类型定义

    如果我有一小段这样的代码 template
  • 让网络摄像头在 OpenCV 中工作

    我正在尝试让我的网络摄像头在 Windows 7 64 位中的 OpenCV 版本 2 2 中捕获视频 但是 我遇到了一些困难 OpenCV 附带的示例二进制文件都无法检测到我的网络摄像头 最近我发现这篇文章表明答案在于重新编译一个文件 o
  • SQLAPI++ 的免费替代品? [关闭]

    Closed 这个问题正在寻求书籍 工具 软件库等的推荐 不满足堆栈溢出指南 help closed questions 目前不接受答案 是否有任何免费 也许是开源 的替代品SQLAPI http www sqlapi com 这个库看起来
  • 如何在C#中控制datagridview光标移动

    我希望 datagridview 光标向右移动到下一列 而不是在向单元格输入数据后移动到下一行 我试图通过 dataGridView1 KeyDown 事件捕获键来控制光标 但这并不能阻止光标在将数据输入到单元格后移动到下一行 提前感谢你的
  • C:设置变量范围内所有位的最有效方法

    让我们来int举个例子 int SetBitWithinRange const unsigned from const unsigned to To be implemented SetBitWithinRange应该返回一个int其中所有
  • 在 C# 的 WebAPI 中的 ApiController 上使用“传输编码:分块”提供数据

    我需要服务分块传输使用编码数据API控制器 因为我无权访问HttpContext or the Http请求 我有点不知道在哪里写入响应以及在哪里刷新它 设置如下 public class MyController ApiControlle
  • 无法访问 GitLab:SSL 证书已过期

    在 Visual Studio 中 我尝试从 GitLab 上的存储库中提取一些更改 但它给了我一个错误 Git 因致命错误而失败 无法访问https gitlab git SSL证书问题 证书已过期 如何生成新证书并将其添加到 VS 中
  • .Net Reactive Extensions Framework (Rx) 是否考虑拓扑顺序?

    Net 反应式扩展框架是否按拓扑顺序传播通知以最大限度地减少更新量 就像 Scala Rx 所做的那样 Net 反应式扩展 Rx 是否可以 https github com lihaoyi scala rx wiki How it Work
  • ContentDialog Windows 10 Mobile XAML - 全屏 - 填充

    我在项目中放置了一个 ContentDialog 用于 Windows 10 上的登录弹出窗口 当我在移动设备上运行此项目时 ContentDialog 未全屏显示 并且该元素周围有最小的填充 在键盘上可见 例如在焦点元素文本框上 键盘和内
  • 如何在 C# 中获取 CMD/控制台编码

    我需要指定正确的代码页来使用 zip 库打包文件 正如我所见 我需要指定控制台编码 在我的例子中为 866 C Users User gt mode Status for device CON Lines 300 Columns 130 K
  • 如何在 ASP.NET Core 中注入泛型的依赖关系

    我有以下存储库类 public class TestRepository Repository

随机推荐