具有统一初始化的 Auto 扩展为意外类型

2023-12-29

考虑这个用 GCC 4.7.2 编译的短程序g++ -std=c++11 test.cc

#include <memory>
#include <queue>

struct type{
  type(int a) : v(a) {}
  int v;
};

typedef std::shared_ptr<type> type_ptr;

int main(){
  int value = 3;
  std::queue<type_ptr> queue;
  auto ptr{std::make_shared<type>(value)};
  queue.push(ptr);
}

编译器输出以下错误:

src/test.cc: In function ‘int main()’:
src/test.cc:15:17: error: no matching function for call to ‘std::queue<std::shared_ptr<type> >::push(std::initializer_list<std::shared_ptr<type> >&)’
src/test.cc:15:17: note: candidates are:
In file included from /usr/include/c++/4.7/queue:65:0,
                 from src/test.cc:2:
/usr/include/c++/4.7/bits/stl_queue.h:211:7: note: void std::queue<_Tp, _Sequence>::push(const value_type&) [with _Tp = std::shared_ptr<type>; _Sequence = std::deque<std::shared_ptr<type>, std::allocator<std::shared_ptr<type> > >; std::queue<_Tp, _Sequence>::value_type = std::shared_ptr<type>]
/usr/include/c++/4.7/bits/stl_queue.h:211:7: note:   no known conversion for argument 1 from ‘std::initializer_list<std::shared_ptr<type> >’ to ‘const value_type& {aka const std::shared_ptr<type>&}’
/usr/include/c++/4.7/bits/stl_queue.h:216:7: note: void std::queue<_Tp, _Sequence>::push(std::queue<_Tp, _Sequence>::value_type&&) [with _Tp = std::shared_ptr<type>; _Sequence = std::deque<std::shared_ptr<type>, std::allocator<std::shared_ptr<type> > >; std::queue<_Tp, _Sequence>::value_type = std::shared_ptr<type>]
/usr/include/c++/4.7/bits/stl_queue.h:216:7: note:   no known conversion for argument 1 from ‘std::initializer_list<std::shared_ptr<type> >’ to ‘std::queue<std::shared_ptr<type> >::value_type&& {aka std::shared_ptr<type>&&}’

指示 auto 类型扩展为初始值设定项列表而不是std::shared_ptr<type>;事实上取代{...} with = ...使代码编译为自动扩展为正确的类型。

我有点惊讶这个看似显而易见的用例未能达到预期的结果。特别是当我记得新的括号初始化语法被吹捧为初始化问题的最终解决方案时。

所以我的问题是:标准中是否有意这样做?或者这是一个疏忽,甚至是一个 gcc 错误?还是我只是想错了?


正如 Xeo 在评论中所说,这是标准行为。7.1.6.4 自动说明符 [dcl.spec.auto]第 6 段规定:

一旦类型a声明符 ID已根据 8.3 确定,声明变量的类型使用声明符 ID使用模板参数推导规则根据其初始值设定项的类型确定。让T是为变量标识符确定的类型d。获得P from T通过替换出现的auto使用新发明的类型模板参数U或者,如果初始化器是大括号初始化列表(8.5.4),其中std::initializer_list<U>。为变量推导的类型d那么推导出来的就是A使用函数调用中的模板参数推导规则确定 (14.8.2.1),其中P是函数模板参数类型和初始化程序d是相应的参数。如果 推导失败,声明格式不正确。

它也被广泛鄙视——有一个委员会正在审查的提案 http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2013/n3681.html更改 C++14 的行为。 C++14 对广义 lambda 捕获的支持加剧了问题 https://groups.google.com/a/isocpp.org/forum/?fromgroups=#!searchin/std-proposals/brace-intialization/std-proposals/YTti2Vy1LGM/Z02smt4udEEJ.

更新:在厄巴纳(参见 CWG Motion 16N4251 WG21 2014-11 厄巴纳会议纪要 http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2014/n4251.html) 委员会申请N3922 从花括号初始化列表自动扣除的新规则 http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2014/n3922.htmlC++17 工作论文。他们决定修复特殊情况,允许auto推导出initializer_list通过增加another特例。auto以同样的方式工作复制列表初始化, 但对于直接列表初始化 from a 大括号初始化列表与单个元素auto直接从该元素推导出来。直接列表初始化从多元素大括号初始化列表现在格式不正确。

这意味着给定

auto x = {42};

x有类型std::initializer_list<int>, but in

auto x{42};

x is an int.

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

具有统一初始化的 Auto 扩展为意外类型 的相关文章

随机推荐

  • find 和 xarg 组合上需要计数器

    所以我有这个代码 find cobacoba type f xargs n 5 bash c a 0 1 2 3 4 echo File a 希望结果 File cobacoba 1 3 cobacoba 1 6 cobacoba 1 q
  • 内容提供程序不与 SqliteDatabase 同步

    我有 2 项活动 ActivityA通过Content Provider访问数据库 并启动ActivityB ActivityB直接访问数据库 我发现之后ActivityB更新了数据库 ActivityA通过CP查询数据库 结果不会更新 但
  • Android 从服务获取屏幕尺寸

    我通过使用活动中的以下内容获得了屏幕尺寸 Display display getWindowManager getDefaultDisplay 但同样的事情在服务中不起作用 出于明显的原因 我知道 但我迫切需要从服务中获取显示尺寸 有人可以
  • AppleScript 或 Automator 用于单击应用程序中的菜单?

    我不确定这是否可以通过 AppleScript 和 或 Automator 实现 但我希望能够 a 启动一个应用程序 我知道这可以通过 AppleScript 或 Automator 轻松完成 b 应用程序启动后 使用 AppleScrip
  • python 中的方法委托

    我正在编写一个用于编排 AWS 集群的小型框架 并且有一些反复出现的常见分层模式 一种这样的模式是将实例集合收集到一个更大的对象中 然后将一些方法直接委托给所有实例 因此 我没有一遍又一遍地复制和粘贴相同的样板代码 而是使用以下模式对其进行
  • 在 C# 中提供方法的同步和异步版本

    我正在用 C 编写一个 API 我想提供公开可用方法的同步和异步版本 例如 如果我有以下功能 public int MyFunction int x int y do something here System Threading Thre
  • 为什么我的 XSL 文件不再应用于我的 XML 文件?

    我在 reports 目录中创建 xml 文件 它们引用样式表 例如 SurveyRespondentList xsl 最新的 Firefox Quantum 68 0 64 位 不接受这一点 以前的版本多年来一直有效我的报告也适用于 In
  • 缩放按钮内的可绘制对象?

    目前我的可绘制对象只是缩放到正常大小 我希望它适合我的按钮 这是它现在的样子 这是按钮的 xml
  • 如何在酒吧上制作3D效果

    I have a very simple basic bar s graphic like this one but i want to display the bars with some 3d effect like this 我只是希
  • 将 int 转换为 int[]

    我有一个数据集 我试图将数据集的所有 Id 放入数据行中 最终将其保存在 int 数组中 它不适合我 它说 Cannot implicitly convert from type int to int Dataset ds new Busi
  • 日期与闰年的差异

    我有 5 周 5 种不同的日程安排 第一周 周一至周五 上午 8 点至下午 5 点 周六和周日休息 第二周 周一至周五 上午 10 点至下午 6 点 周六和周日休息 第三周 周一至周五 上午 11 点至晚上 7 点 周六和周日休息 第四周
  • 为 Blend 和 VS 提供设计时 ViewModel 数据

    在基于 MVVM 的应用程序中 我必须在设计时提供哪些选项来提供 ViewModel 数据 以便我们的设计人员实际上可以在 Blend3 和 VS 2008 中看到一些内容 你怎么做这个 我可以利用 mc ignorable 来实现这一点吗
  • Gradle 缩小所有 javascript

    我正在尝试缩小应用程序中的所有 js 文件 我正在使用gradle js 插件 https github com eriwen gradle js plugin 我能够使用它来缩小单个文件 但我希望我的所有 js 文件都被缩小 这是我尝试过
  • Azure Pipelines 多存储库如何获取 Git 提交 ID

    对于具有多个存储库的 Azure Pipeline 如何从签出的资源存储库中获取 GIT 提交 ID 支持吗 我使用 Azure 存储库来存储管道 yaml 文件 并检查代理上的构建源以在那里进行构建 我们使用的是 Delphi 所以我们必
  • 在过滤器管道上使用多个字段 |角4

    我想知道如何使用 Pipe 使用多个输入字段来过滤 json 对象 这是我到目前为止只有一个字段按名称过滤的代码 TS members name Carl country Brazil name John country United St
  • 使用 Jquery 进行多个过滤器

    我的页面中有一些 div 使用 php jquery 构建 我想根据它们的属性过滤它们 如果有超过 1 个属性过滤 则会缩小搜索范围 div 看起来像这样 div div title Mike Whatever content 1 div
  • 将 WWW 重定向到非 WWW,或者反之亦然? [关闭]

    很难说出这里问的是什么 这个问题是含糊的 模糊的 不完整的 过于宽泛的或修辞性的 无法以目前的形式得到合理的回答 如需帮助澄清此问题以便重新打开 访问帮助中心 help reopen questions 我刚刚在我的网站上进行了搜索引擎优化
  • 使用 Google Sheets API,当我输入数据时,不支持添加和更新列格式

    所以 这实际上是一个基于我上次尝试的后续问题 如何使用 API 将列添加到 Google Sheets 并在同一调用中提供列的名称和类型 https stackoverflow com questions 57259399 how to a
  • 高效的java对象图序列化

    序列化 java 对象图的最佳方法是什么 我对序列化库的要求是 1 反序列化速度 2 size 尽可能小 小于java默认序列化中的大小 3 灵活性 基于注释的定义必须序列化的内容会很好 底层文件格式并不重要 我查看了Protocol Bu
  • 具有统一初始化的 Auto 扩展为意外类型

    考虑这个用 GCC 4 7 2 编译的短程序g std c 11 test cc include