news 2026/6/10 1:08:20

【Effective Modern C++】第三章 转向现代C++:7. 在创建对象时注意区分()和{}

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
【Effective Modern C++】第三章 转向现代C++:7. 在创建对象时注意区分()和{}

初始化的基本方式

指定初始化的方式包括使用小括号、使用等号,或是使用大括号:

int x(0); int y = 0; int z{0};

很多情况下使用一个等号和一对大括号也是可以的:(处理方式等同于只有大括号)

int z = {0};

对于用户定义的类型,等号的初始化方式实际并没有发生赋值:

Widget w1; // 调用的是默认构造函数 Widget w2 = w1; // 井非赋值,调用的是复制构造函数 w1 = w2; // 并非赋值.调用的是复制赋值运算符

C++11引入了统一初始化:使用大括号进行初始化。

  1. 使用大括号来制定容器的初始内容:
std: :vector<int> v{ 1, 3, 5 }; // v 的初始内容为1、3、5
  1. 为非静态成员指定默认初始化值(也可以使用“=”,但是()不行):
class Widget { ... private: int x{ 0 }; // 可行,x 的默认值为 0 int y = 0; // 也可行 int z(0); // 不可行! };

不可复制对象(如std::atomic类型的对象)可以使用大括号和小括号来进行复制,但是不能使用“=”。

由上可以看出,只有大括号初始化适用于所有场景

大括号初始化的特性

  1. 禁止内建类型之间进行隐式窄化类型转换。如果大括号内的表达式无法保证能够采用进行初始化的对象来表达,则代码不能通过编译。
    如:
double x, y, z; int sum1{ x + y + z }; // 错误!double类型之和可能无法用int表达
  1. 对于C++最令人苦恼的解析语法(MVP:任何能够解析为声明的都要解析为声明。最苦恼——程序员本来想要以默认方式构造一个对象,却不小心声明了一个函数)免疫。
    如:
Widget w1(); // 解析为函数声明(MVP问题) Widget w2{}; // 明确为对象初始化,无歧义

存在的缺陷

1.auto变量的异常推导

auto结合{}初始化时,变量类型会被推导为std::initializer_list(而非直觉类型):

auto a = 10; // 推导为int(符合直觉) auto b{10}; // C++11/14:std::initializer_list<int>;C++17后:int auto c = {10, 20}; // 始终推导为std::initializer_list<int>

2. 构造函数重载决议的优先级规则

  • std::initializer_list形参时(){}初始化结果一致:
class Widget { public: Widget(int i, bool b); // 无std::initializer_list形参 Widget(int i, double d); … }; Widget w1(10, true); // 调用第一个构造函数 Widget w2{10, true}; // 调用第一个构造函数 Widget w3(10, 5.0); // 调用第二个构造函数 Widget w4{10, 5.0}; // 调用第二个构造函数
  • std::initializer_list形参时{}强制优先匹配该构造函数(即使普通构造更匹配):
class Widget { public: Widget(int i, bool b); Widget(int i, double d); Widget(std::initializer_list<long double> il); // 新增 … }; Widget w1(10, true); // 调用第一个构造函数(()不受影响) Widget w2{10, true}; // 调用std::initializer_list构造(10/true转long double) Widget w3(10, 5.0); // 调用第二个构造函数(()不受影响) Widget w4{10, 5.0}; // 调用std::initializer_list构造(10/5.0转long double)
  • 优先级极端性:即便std::initializer_list构造无法调用,编译器仍会优先尝试(失败才回退普通决议):
class Widget { public: Widget(int i, bool b); Widget(int i, double d); Widget(std::initializer_list<bool> il); // 元素类型为bool … }; Widget w{10, 5.0}; // 错误!10/5.0转bool属于窄化转换,{}禁止
  • {}的边界规则:空{}表示 “无实参”,优先调用默认构造(而非空std::initializer_list);需传空列表时需嵌套括号:
class Widget { public: Widget(); // 默认构造 Widget(std::initializer_list<int> il); // std::initializer_list构造 … }; Widget w1; // 调用默认构造 Widget w2{}; // 调用默认构造 Widget w3(); // MVP!声明函数 Widget w4({}); // 调用std::initializer_list构造(空列表) Widget w5{{}}; // 同上

3.std::vector(){}初始化结果差异巨大

std::vector<int> v1(10, 20); // 非std::initializer_list构造:10个元素,值均为20 std::vector<int> v2{10, 20}; // std::initializer_list构造:2个元素,值为10、20

总结

  • 大括号初始化可以应用的语境最为宽泛,可以阻止隐式窄化类型转换,还对最令人苦恼之解析语法免疫。
  • 在构造函数重载决议期间,只要有任何可能,大括号初始化物就会与带有std::initializer_list类型的形参相匹配,即使其他重载版本有着貌似更加匹配的形参表。
  • 对于数值类型的std::vector来说使用大括号初始化和小括号初始化会造成巨大的不同
  • 在模板内容进行对象创建时,使用小括号还是大括号会成为一大挑战。

原著在线阅读地址

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/6/5 0:50:22

NewBie-image-Exp0.1完整指南:从镜像拉取到图片输出全流程详解

NewBie-image-Exp0.1完整指南&#xff1a;从镜像拉取到图片输出全流程详解 1. 引言&#xff1a;为什么选择 NewBie-image-Exp0.1 预置镜像&#xff1f; 你是否曾为部署一个动漫图像生成模型而烦恼&#xff1f;环境依赖复杂、源码Bug频出、权重下载缓慢——这些问题常常让刚入…

作者头像 李华
网站建设 2026/6/5 0:35:08

OpenCV JavaScript:在浏览器和Node.js中实现计算机视觉

OpenCV JavaScript&#xff1a;在浏览器和Node.js中实现计算机视觉 【免费下载链接】opencv-js OpenCV JavaScript version for node.js or browser 项目地址: https://gitcode.com/gh_mirrors/op/opencv-js OpenCV JavaScript 是一个专门为JavaScript环境设计的计算机视…

作者头像 李华
网站建设 2026/6/9 17:47:07

R语言森林生态系统结构、功能与稳定性分析与可视化实践高级应用

在生态学研究中&#xff0c;森林生态系统的结构、功能与稳定性是核心研究内容之一。这些方面不仅关系到森林动态变化和物种多样性&#xff0c;还直接影响森林提供的生态服务功能及其应对环境变化的能力。森林生态系统的结构主要包括物种组成、树种多样性、树木的空间分布与密度…

作者头像 李华
网站建设 2026/6/9 18:54:55

Qwen3-1.7B体验报告:小参数也有大能量

Qwen3-1.7B体验报告&#xff1a;小参数也有大能量 1. 引言&#xff1a;轻量模型也能“思考”&#xff1f; 你有没有想过&#xff0c;一个只有17亿参数的AI模型&#xff0c;也能像大模型一样“边想边答”&#xff1f;这不是未来科技&#xff0c;而是已经到来的现实——Qwen3-1…

作者头像 李华
网站建设 2026/6/9 18:37:40

快速掌握数据采集工具:新手入门完整指南

快速掌握数据采集工具&#xff1a;新手入门完整指南 【免费下载链接】MediaCrawler 项目地址: https://gitcode.com/GitHub_Trending/mediacr/MediaCrawler 在当今数据驱动的时代&#xff0c;一款优秀的数据采集工具能够帮助我们从各大社交平台高效提取有价值的信息。M…

作者头像 李华
网站建设 2026/6/9 19:43:52

fft npainting lama图像处理状态解析:从初始化到推理完成全链路

fft npainting lama图像处理状态解析&#xff1a;从初始化到推理完成全链路 1. 引言&#xff1a;图像修复的实用价值与技术背景 你有没有遇到过这样的情况&#xff1f;一张珍贵的照片里有个不想要的路人&#xff0c;或者截图上的水印遮挡了关键信息。手动用PS一点点修补太费时…

作者头像 李华