带和不带 ( ) 的构造函数调用之间的区别

2024-03-15

我是 C++ 初学者,想了解为什么

return std::list<int>();

需要括号,但是

std::list<int> foo;

不需要括号。这些构造函数调用有什么区别?


这些都不是构造函数调用。

第一个是显式类型转换 http://en.cppreference.com/w/cpp/language/explicit_cast,它创建一个类型的对象std::list<int>.

第二个是变量定义,它创建类型的对象std::list<int>.

在这两种情况下,默认构造函数(不带参数的构造函数)都会作为创建的一部分被调用。

尽管您可能会看到诸如“构造函数调用”之类的内容,但在 C++ 中没有显式且单独调用构造函数的语法结构。

一个需要括号而另一个不需要括号的原因是因为它们是具有不同语法的两种独立的语言构造,而不是调用构造函数的两种方法。


请注意,如果您在第二个示例中添加括号,您实际上声明了一个函数而不是定义了一个变量:

std::list<int> foo; //variable definition
std::list<int> foo(); //function taking no args, returning a std::list<int>

这通常被称为最麻烦的解析 https://stackoverflow.com/questions/1424510/most-vexing-parse-why-doesnt-a-a-work。 C++11 引入了花括号初始化来解决这个问题:

std::list<int> foo{}; //variable definition

标准语,对于那些愿意的人

(引自N3337)

"But T()当然看起来像构造函数调用,为什么不是呢?”

在这种背景下,T()称为带有函数符号的显式类型转换:

5.2.3 显式类型转换(函数表示法)[expr.type.conv]

1 [...]

2 表达方式T(), where T是非数组完整对象类型或(可能是 cv 限定的)void 类型的简单类型说明符或类型名称说明符,创建指定类型的纯右值,该类型是值初始化的(8.5;对于 void() 情况不进行初始化)。 [注:如果T是一个非类类型 cv 限定符,在确定结果纯右值 (3.10) 的类型时忽略 cv 限定符。 ——尾注]

所以这创建了一个prvalue这是值初始化.

[dcl.init]/7: To 值初始化类型的对象T means:

如果 T 是一个(可能是 cv 限定的)类类型(第 9 条),具有用户提供的构造函数 (12.1),则调用 T 的默认构造函数(如果 T 没有可访问的默认值,则初始化是错误的 构造函数);

— [...]

因此,这将调用构造函数作为值初始化的一部分,这是显式类型转换的一部分。如上所述,无法直接调用构造函数。标准说:

[class.ctor]/1:构造函数没有名字。使用特殊的声明符语法来声明或定义构造函数。 语法使用:

— 可选的 decl-specifier-seq,其中每个 decl-specifier 是函数说明符或 constexpr,

— 构造函数的类名,以及

— 参数列表

以该顺序。在这样的声明中,构造函数类名周围的可选括号将被忽略。

因此构造函数没有名称,我们使用语言定义的语法异常来声明/定义它们。

“这看起来像是一种学术上的区别,这在实践中重要吗?”

也许,也许不是。我的观点是,将上述语法解释为纯构造函数调用会错误地描述构造函数是什么。构造函数初始化一个对象;它不会分配该对象的内存、返回初始化的对象、将符号绑定到该对象或通过变量定义和类型转换完成的任何其他操作。此外,它可能会造成像OP一样的混乱,OP希望统一语法,因为他认为这两个构造都是构造函数调用。

当我们有避免混淆的正式术语时,为什么要使用不精确的提喻法呢?

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

带和不带 ( ) 的构造函数调用之间的区别 的相关文章

随机推荐

  • Flutter - 自定义按钮点击区域

    我正在构建一个 Flutter 应用程序 其中屏幕的很大一部分将被圆形按钮占据 我已经尝试了几种不同的方法来创建圆形按钮 但我总是遇到同样的问题 可点击 区域实际上不是圆形的 而是矩形的 这是一个使用以下方法获得的示例FloatingAct
  • 按任意键对元组列表进行排序

    order w x a z object a object x object z object a object w 如何根据 order 提供的键列表按第二个元素对上面的元组列表进行排序 2013 年 11 月 18 日更新 我发现了一个
  • 将值加载到 Selectize.js 中

    Problem 我有一个文本输入 我选择它作为标签 它可以很好地查询远程数据 我可以使用它搜索甚至创建新项目 并且一切正常 使用选择 var select authorsearch selectize valueField AuthorId
  • 使用 JavaScript 切换 CSS 类 - 错误

    我正在尝试制作一个脚本 当用户单击具有 burger nav img 类的图像时 它会在另一个元素中切换 open 类 我的代码是 HTML
  • Swing - 使用 getComponent() 更新所有 JButton

    我正在制作一个井字棋游戏 其中每个棋盘都由一个 JButton 代表 当有人单击该按钮时 文本将更改为 X 或 O 我正在编写一个重置函数 它将所有按钮中的文本重置为 我正在使用 getComponents 方法访问数组中的所有按钮 我只是
  • 为 GridView 的 PagerTemplate 动态生成页面链接按钮

    从 MSDN 页面获取PagerTemplate of the GridView控制 强调我的 通常 按钮控制添加到寻呼机模板中以执行寻呼操作 当单击 CommandName 属性设置为 Page 的按钮控件时 GridView 控件将执行
  • 是否可以在不使用 ApplicationContextAware 的情况下检索具有原型范围的 Spring bean

    使用Spring 3 1 如果我想检索具有原型范围的 bean 即我每次都想要该类的不同实例 是否可以在不使用 ApplicationContextaware 类的情况下检索该 bean 这就是我目前的做法 Component Qualif
  • ModuleNotFoundError:没有名为“建模”的模块

    我对深度学习和 python 非常陌生 我正在尝试重新创建该项目https github com Nagakiran1 Extending Google BERT as Question and Answering model and Ch
  • 能否阻止单个应用程序的 Microsoft 错误报告?

    我们有一个非托管 C 应用程序 它利用第 3 方 API 来读取 CAD 文件 对于某些损坏的 CAD 文件 第 3 方库崩溃并导致我们的 EXE 崩溃 因此 我们的主应用程序是一个单独的 EXE 这样它就不会受到崩溃的影响 然而 我们最终
  • 使用 java POI 插入表时 Open Office writer 崩溃

    我正在尝试使用 open office 使用 apache poi 以 docx 格式插入表 但是每次打开文件时文件都会崩溃 XWPFDocument document new XWPFDocument FileOutputStream o
  • 单击浏览器的后退按钮时重定向到特定页面

    这是一个有点菜鸟的问题 但事实就是这样 我有一个网站 用户只能通过下一页和后退按钮从一个页面导航到另一个页面 即有一个用户必须遵循的向导 向导的一部分包含不同的页面 一部分包含相同的页面但具有更改的 div 但从用户体验来看 它是不同的页面
  • Stream_Copy_To_Stream() 的替代方案 php

    我现在正在开发一个文件共享网站 遇到了一个小问题 我正在使用上传脚本 uploadify 它工作得很好 但如果用户想要 我希望上传的文件被加密 现在我有可以执行此操作的工作代码 如下所示 但我的服务器只有 1GB 或内存 并且使用strea
  • 如何在 WooCommerce 3+ 中进行调试

    我正在使用本教程为 Woocommerce 创建自定义运输方法https docs woocommerce com document shipping method api https docs woocommerce com docume
  • 如何“重置”给定 HTML 元素的样式?

    我正在开发一个可嵌入的 javascript 它将 HTML 元素插入未知页面 我无法控制要插入 HTML 的页面的样式表 问题是我插入的 HTML 会被页面错误地风格化 我想防止这种情况发生 确保我插入的元素是最不冗长和 或资源密集的ex
  • 使用 pd.read_clipboard 复制多索引数据帧?

    Given a 像这样的数据框 https stackoverflow com questions 17921010 how to query multiindex index columns values in pandas C A B
  • Swift Codable:使用未知键解码字典

    Codable当您了解 JSON 数据的关键格式时 这会非常有用 但是如果您不知道密钥怎么办 我目前面临这个问题 通常我希望 JSON 数据像这样返回 id lt 123 gt data id
  • 如何用颜色填充位图对象中的封闭区域

    给区域内的点赋予颜色来填充区域 类似于油漆桶功能中的 绘图 这 NET Framework 中 没有直接的等效项 但我希望使用 C 来做到这一点 是否可以 这是一个非常简单的洪水填充算法 应该可以帮助您入门 void Form1 Paint
  • 在不知道父元素的情况下访问多维数组元素

    我有返回以下多维数组的函数 我无法控制数组的形成方式 我正在尝试访问 结果 元素 这个问题是 父元素的名称不断变化 Result 元素的位置始终相同 因为名称为 Result 是否可以在不知道父元素名称的情况下访问该元素 Array sHe
  • UITableViewCell 异步加载图像问题 - Swift

    在我的应用程序中 我构建了自己的异步图像加载类 我传入一个对象 然后它检查缓存 NSCache 是否有图像 如果没有 它将检查文件系统是否已保存图像 如果图像尚未保存 它将在后台下载图像 NSOperations 帮助 到目前为止 效果很好
  • 带和不带 ( ) 的构造函数调用之间的区别

    我是 C 初学者 想了解为什么 return std list