了解编译器如何在初始化中使用普通的 {}-list

2024-04-30

考虑以下玩具代码:

class Y
{
public:
    Y(int, int) { cout << "Y ctor\n"; }
};

class X
{
public:
    //X(initializer_list<int>) { cout << "init\n"; }      // 1
    X(Y&&) { cout << "Y&&\n"; }                         // 2
    X(int, int) { cout << "param\n"; }                  // 3
    X(const X&) { cout << "X&\n"; }                     // 4
    X(const Y&) { cout << "Y&\n"; }                     // 5
    X(Y) { cout << "Y\n"; }                             // 6
    X(X&&) { cout << "X&&\n"; }                         // 7
};

void f(const X&) {  }
void f(const Y&) {  }
void f(Y) {  }

int main()
{
    X x({1,2});
    //f({ 1,2 });                                         // 8
}

我试图了解编译器如何使用{1,2} in X x({1,2})。以下是我的理解:

  • 取消注释行1

    在这种情况下,我认为X x({1,2})是一个明确的呼吁X(initializer_list<int>)。也就是说,当编译器看到{}-list,我想它首先会看到它std::initializer_list和一个带有参数的构造函数initializer_list<T>将是比所有其他人更好的匹配。

  • 注释掉行6, 7

    在这种情况下,我认为{1,2}用于构造一个对象Y它与右值引用绑定(即编译器选择调用X(Y&&))。我的猜测是编译器会处理{1,2}当没有构造函数接受参数时,作为某种右值initializer_list<T>,因此首选采用右值引用的构造函数(在本例中,X(Y&&)是此类的唯一构造函数)。

    Update:我发现我在这个要点中描述的行为实际上是bug https://godbolt.org/z/ozad3aTxxMSVC 的。 gcc 和 clang 会报告歧义,不调用X(Y&&)

  • 注释掉行7

    出现歧义。编译器报告两者X(Y&&) and X(Y)匹配。我认为这是因为虽然X(Y&&)是一个比更好的匹配X(const Y&) and X(const X&), 无法区分X(Y)。 (我觉得这里的逻辑很扭曲)

    可能的参考 https://stackoverflow.com/a/17961890/16500459.

  • 注释掉行2,7

    代码编译并打印param。我想这一次X(const X&)被选择但我不知道为什么。我对此的猜测是,当所有可行的匹配时(X(const X&), X(const Y&) and X(Y))是无法区分的,编译器选择X(const X&)因为X x({1,2});正在建造一个X.

    Update:这也可以是 MSVCbug https://godbolt.org/z/TPbx7r7aE。 gcc 和 clang 会报告歧义,不调用X(const X&)

  • 注释掉行2,7并取消注释行8

    我认为在这种情况下,所有可行的匹配都是无法区分的,并且f不是一个构造函数X, hence f(const X&)没有得到特殊对待,就会产生歧义。

请问我的理解是否正确? (我非常怀疑它们是否准确)


我发现读取构造函数被诸如此类的东西调用是相当乏味的X x({1,2});,所以我想在实际代码中我们应该尽量避免这种速记并以更明确的方式编写代码......


另一方面,如果我们对类使用相同的设置X and Y如上,定义并调用一个函数g如下:

X g()
{
    return { 1,2 };
}

int main()
{
    g();
}

结果似乎总是等同于通过以下方式初始化返回的临时值X{1,2}(即致电X(initializer_list<int>)当它存在时,并且在所有其他情况下调用X(int, int))。请问这是真的吗?


  1. X x({1,2})不能是“明确要求”std::initializer_list: a 大括号初始化列表 has no type。但是,有一条规则规定,与任何其他类类型相比,该模板更适合该模板的专门化。
  2. X(Y&&)被使用是因为X(const X&)不可行。它将被视为second用户定义的转换即使{…}YX不是(因为有两层初始化)。
  3. Yes, Q and Q&&常常是这样暧昧的。考虑一下 C++17 纯右值甚至不会进行初始化。
  4. 大概你的意思是你注释掉了第 2 行和第 6 行。在这种情况下,来自(引用)的构造函数X如上所述被取消资格,并且X(const Y&)是一个更糟糕的匹配,因为const必须是added到非常量列表初始化的纯右值。 (否则所有用户定义的转换都无法区分。)
  5. f(Y)无论如何都比其他两个好X的构造函数相同const reason.

As for g,是的,在没有的情况下,复制列表初始化与直接列表初始化非常相似explicit构造函数。自从它is列表初始化,而不是直接从“参数”初始化大括号初始化列表, it does与其他所有构造函数相比,更喜欢初始化列表构造函数。

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

了解编译器如何在初始化中使用普通的 {}-list 的相关文章

  • 在 Web 浏览器中禁用 F5 [重复]

    这个问题在这里已经有答案了 可能的重复 禁用浏览器的后退按钮 https stackoverflow com questions 961188 disable browsers back button 如何禁用浏览器上的 F5 刷新 htt
  • 从 Invoke 方法获取 RETURN

    我正在尝试从另一个线程上的列表框项目中读取值 我尝试创建一种新方法来运行调用命令 我可以设法将命令发送到列表框 例如通过调用方法添加 但我似乎无法得到响应 我似乎无法获取该项目的值 我尝试了几种方法 一旦我将它从空变为字符串 事情就开始变得
  • 通过另一个列表更新列表(linq)

    我有类 Data 的对象列表 如下所示 class Data int code string name DateTime date update 我还有另一个课程列表 例如 class RefCodes int old code int n
  • 在 Mac OS X 上安装 libxml2 时出现问题

    我正在尝试在我的 Mac 操作系统 10 6 4 上安装 libxml2 我实际上正在尝试在 Python 中运行 Scrapy 脚本 这需要我安装 Twisted Zope 现在还需要安装 libxml2 我已经下载了最新版本 2 7 7
  • MSMQ接收和删除

    是否有任何选项可以在读取消息后将其从 MSMQ 中删除 比如 接收 删除可以作为原子操作运行吗 听起来您想查看下一条消息 然后在处理完成后接收它 Message message Queue Peek Queue ReceiveById me
  • 如何查明 .exe 是否正在 C++ 中运行?

    给定进程名称 例如 程序 exe C 标准库没有这样的支持 您需要一个操作系统 API 来执行此操作 如果这是 Windows 那么您将使用 CreateToolhelp32Snapshot 然后使用 Process32First 和 Pr
  • 虚拟并行端口模拟器

    在我的计算机网络课程中 我们应该通过使用本机寄存器 例如使用 outportb 等命令 来学习并行端口编程 我没有并行端口 因为我住在 2011 年 但想练习这些程序 我使用 dosbox 安装了旧的 Turboc 3 IDE 有没有一个程
  • C# Winforms Designer 无法打开,因为它无法在同一程序集中找到类型

    我收到以下错误 找不到类型 My Special UserControl 请确保引用包含此类型的程序集 如果此类型是您的开发项目的一部分 请确保已使用当前平台或任何 CPU 的设置成功构建该项目 但没有任何意义的是My Special Us
  • 为什么 std::function 不是有效的模板参数,而函数指针却是?

    我已经定义了名为的类模板CallBackAtInit其唯一目的是在初始化时调用函数 构造函数 该函数在模板参数中指定 问题是模板不接受std function作为参数 但它们接受函数指针 为什么 这是我的代码 include
  • 如何在 EF Core 2.1 中定义外键关系

    我的 DAL 使用 EF Core 2 1 这就是我的模型的样子 一名用户只能拥有一种角色 Role entity kind of master public class Role public int RoleId get set pub
  • MSChart 控件中的自定义 X/Y 网格线

    我有一个带有简单 2D 折线图的 C Windows 窗体 我想向其中添加自定义 X 或 Y 轴标记 并绘制自定义网格线 例如 以突出显示的颜色 虚线 我查看了 customLabels 属性 但这似乎覆盖了我仍然想显示的默认网格 这是为了
  • C 与 C++ 中的 JNI 调用不同?

    所以我有以下使用 Java 本机接口的 C 代码 但是我想将其转换为 C 但不知道如何转换 include
  • 选择 asp.net CheckBoxList 中的所有项目

    ASP NET 和 C 我想要一个带有 全选 项目的复选框列表 当这个特定项目是 已选择 所有其他都将被选择 也 当选择被删除时 这个项目 也将来自所有人 其他物品 选中 取消选中 任何其他项目只会有一个 对特定项目的影响 无论选择状态如何
  • 使用 Unity 在 C# 中发送 http 请求

    如何使用 Unity 在 C 中发送 HTTP GET 和 POST 请求 我想要的是 在post请求中发送json数据 我使用Unity序列化器 所以不需要 新的 我只想在发布数据中传递一个字符串并且能够 将 ContentType 设置
  • 在 Qt 中播放通知(频率 x)声音 - 最简单的方法?

    Qt 5 1 或更高版本 我需要播放频率为 x 的通知声音 n 毫秒 如果我能像这样组合音调那就太好了 1000Hz 持续 2 秒 然后 3000Hz 持续 1 秒 最简单的方法是使用文件 WAV MP3 例如如此处所述 如何用Qt播放声音
  • 在二进制数据文件的标头中放入什么

    我有一个模拟 可以读取我们创建的大型二进制数据文件 10 到 100 GB 出于速度原因 我们使用二进制 这些文件依赖于系统 是从我们运行的每个系统上的文本文件转换而来的 所以我不关心可移植性 当前的文件是 POD 结构的许多实例 使用 f
  • 使用 boost 异步发送和接收自定义数据包?

    我正在尝试使用 boost 异步发送和接收自定义数据包 根据我当前的实现 我有一些问题 tcpclient cpp include tcpclient h include
  • 运行 xunit 测试时无法将输出打印到控制台窗口

    public class test2InAnotherProject private readonly ITestOutputHelper output public test2InAnotherProject ITestOutputHel
  • Emacs C++,打开相应的头文件

    我是 emacs 新手 我想知道 是否有在头文件 源文件和相应的源文件 头文件之间切换的快捷方式 是否有像通用 emacs 参考卡那样的参考卡 Thanks There s ff find other file 您可以使用以下方法将其绑定到
  • IDisposable 的显式实现

    虽然有很多关于IDisposable在 SO 上找到 我还没有找到答案 我通常遵循这样的做法 当我的一个班级拥有一个IDisposable对象然后它也实现IDisposable并打电话Dispose在拥有的对象上 然而最近我遇到了一个类 它

随机推荐

  • 比较字符变量

    我想在 R Studio 中比较两个不同的字符变量 第一列 BZ Pred 显示参与者预测的 5 个最常用的应用程序 第二列 BZ Act 显示实际使用最多的 5 个应用程序 现在我想创建第三列 如果第一个应用程序被正确猜测 则包含 是 如
  • ASP.NET 中的网络凭据错误

    我正在尝试使用 NetworkCredential 类通过 ASP NET 访问网页 但是我不断收到以下消息的异常System Security Cryptography CryptographicException The handle
  • 为什么在将应用程序部署到 Heroku 时会出现此错误?

    使用 git hub 将应用程序部署到 heroku 时遇到某种错误 问题是 我不理解 heroku 日志和随之而来的错误 这是 Heroku 日志 Marcuss MacBook Pro Weather App marcushurney
  • 公钥的长度(加密)可以与私钥不同吗?

    我有一个 1024 位的私钥 并用它来生成公钥 这是否自动意味着我的公钥也具有 1024 加密 或者它的加密大小可以更小吗 512 256 PS 我最感兴趣并谈论的是 RSA 密钥中模数 n 的大小 大小通常为 1024 或 2048 位
  • 启用 WCF 数据服务默认接受/返回 JSON

    我有一个 WCF 数据服务 我希望默认情况下为所有操作返回 JSON 我可以在配置 通过服务属性中设置它吗 为了通过 format 标签启用 json 如下所示 host 8038 YourService svc format json 将
  • 您会在新的商业项目中使用 S#arp 架构吗?

    The S arp 架构 http code google com p sharp architecture 看起来真的很酷 但是您是否认为它仍然太新而无法在重要的新项目中做出承诺 我们假设该项目乍一看很适合它 It all seems非常
  • 无法在 XAMPP 和 Windows XP 上安装 Xdebug

    我知道 这个问题已经被问过好几次了 但答案并没有解决我的问题 我在 Windows XP SP3 上运行 XAMPP 1 8 2 并且在安装 XDebug 时遇到困难 我从网站下载了XDebug 不幸的是 安装向导对我不起作用 我的 PHP
  • 如何在 CSV 文件中插入新行?

    我正在创建一个系统 其中涉及创建用于错误记录的 CSV 我当前的代码成功创建了一个具有唯一名称的新文件 然后将现有数据 来自数组 添加到 CSV 中 我遇到的问题是在文件中添加新行 这是维持正确结构所必需的 我现有的代码 current f
  • rvm 监控延迟作业

    我正在尝试使用 monit 运行delayed job 但它无法运行 因为 rvm 的路径 每个用户的本地 rvm 安装 对该命令不可用 我的应用程序是一个带有捆绑器的rails2应用程序 Monit 无法找到捆绑程序 有人对我如何了解 m
  • 致命错误:未找到“MongoDB\Driver\Manager”类

    我想使用 MongoDB 驱动程序 但当我使用它时 它抛出一个错误 mongo new MongoDB Driver Manager mongodb localhost 27017 错误 消息 未找到类 MongoDB Driver Man
  • 合并 Pandas Dataframe:如何添加列和替换值

    我有一个数据帧 df1 并想要合并其他 许多 数据帧 df2 以便 合并发生在匹配的 多 索引上 如果缺失 将创建新列 如果列已存在 则替换值 正确的 pandas 操作是什么以及使用什么参数 我查看了 concat join merge
  • 解析 JSONException:JSONArray 文本必须以字符 1 处的 '[' 开头

    我正在尝试将 Android 应用程序与本地 MySQL 数据库连接 但遇到问题 解析 JSON 数组 我在这里阅读了所有类似的问题 但没有任何作用 错误消息 Error parsing data org json JSONExceptio
  • 使用 Sheets API v4 获取与 Google 帐户关联的所有电子表格的列表

    使用 Google Sheets API v4 我希望获取附加到我的帐户的电子表格列表 我做了很多研究 但还没有找到任何解决方案 v4 API 不提供列出电子表格的方法 您需要使用 Drive API 这从以前的 API 页面迁移 http
  • Mongodb 获取聚合框架中的最后组合

    有一个消息集合 date NumberLong 1421134514 sender 53172480f9cd0e682840b9f7 recipient 52f37fbaf9cd0e02773c97b1 isRead false id 54
  • Office 365 默认日历的 ID 自动更改

    我使用 Office 365 API 的 V2 DLL 来执行日历操作 我正在保存默认日历的 ID 以对其执行操作 从过去两年开始 它对我来说工作得很好 但最近自从上 1 个月以来 当我尝试从我的帐户中获取日历时 只是为了检查日历是否适用于
  • 如何使用正则表达式提取字符串进行词性标记

    参考question https stackoverflow com questions 44434739 how to extract a string before and after slash in r 我在以下示例的解决方案中面临
  • 如何在 C 中的 for (;;) 循环中声明多个变量?

    我认为可以在一个变量中声明多个变量for loop for int i 0 char ptr bam i lt 10 i 但我刚刚发现这是不可能的 GCC 给出以下错误 错误 char 之前应有不合格的 id 你真的不能在一个变量中声明不同
  • 如何编写允许特殊字符 DOT 的正则表达式?

    如何编写允许用户名中包含字符 DOT 的正则表达式 例如 R Robert X A Pauline 用反斜杠转义点
  • PHP - 根据一个值查找具有不同结构的两个多维数组之间的差异

    我正在努力理解哪种数组函数最适合我的特定情况 其他人似乎有很多困惑 我也读过几篇文章 我有两个具有不同结构的数组 但都包含一个我想比较的 ID 字段 数组一是我的素材数组 它看起来像 array 1 0 gt array 5 ID gt s
  • 了解编译器如何在初始化中使用普通的 {}-list

    考虑以下玩具代码 class Y public Y int int cout lt lt Y ctor n class X public X initializer list