C++17新特性-新的括号初始化规则

简介

C++11引入了新的括号初始化语法{} 。其不仅允许集合式初始化,而且还是对常规构造函数的调用。遗憾的是,当与auto 类型变量结合时,这种方式就很容易出现错误。C++17将会增强这一系列初始化规则。本节中,我们将了解到如何使用C++17语法正确的初始化变量。

语法定义

一步初始化所有变量。使用初始化语法时,注意两种不同的情况:

不使用auto声明的括号初始化:

// Three identical ways to initialize an int:
int x1 = 1; int x2{1};
int x3(1);

std::vector<int> v1{1, 2, 3}; // Vector with three ints std::vector<int> v2 = {1, 2, 3}; // same here
std::vector<int> v3(10, 20); // Vector with 10 ints, each have value 20

使用auto声明的括号初始化:

auto v {1}; // v is int
auto w {1, 2}; // error: only single elements in direct
// auto initialization allowed! (this is new) auto x = {1}; // x is std::initializer_list<int>
auto y = {1, 2}; // y is std::initializer_list<int>
auto z = {1, 2, 3.0}; // error: Cannot deduce element type

工作流

无auto 类型声明时, {} 的操作没什么可大惊小怪的。当在初始化STL容器时,例如std::vector , std::list 等等,括号初始化就会去匹配std::initializer_list (初始化列表)的构造函数,从而初始化容器。其构造函数会使用一种“贪婪”的方式,这种方式就意味着不可能匹配非聚合构造函数(与接受初始化列表的构造函数相比,非聚合构造 函数是常用构造函数)。

  • std::vector 就提供了一个特定的非聚合构造函数,其会使用任意个相同的数值填充vector 容器:
  • std::vector v(N, value) 。当写成std::vector v{N, value} 时,就选择使用
  • initializer_list 的构造函数进行初始化,其会将vector 初始化成只有N和value两个元素的变量。这个“陷阱”大家应该都知道。
  • {} 与() 调用构造函数初始化的方式,不同点在于{} 没有类型的隐式转换,比如int x(1.2); 和int x = 1.2; 通过静默的对浮点值进行向下取整,然后将其转换为整型,从而将x的值初始化为1。相反的, int x{1.2}; 将会遇到编译错误,初始化列表中的初始值,需要与变量声明的类型完全匹配。

注意: 哪种方式是最好的初始化方式,目前业界是有争议的。括号初始化的粉丝们提出,使用括号的方式非常直观,
直接可以调用构造函数对变量进行初始化,并且代码行不会做多于的事情。另外,使用{}括号将会是匹配构造
函数的唯一选择,这是因为使用()进行初始化时,会尝试匹配最符合条件的构造函数,并且还会对初始值进行
类型转换,然后进行匹配(这就会有处理构造函数二义性的麻烦)。

C++17添加的条件也适用于auto(推断类型)——C++11引入,用于正确的推导匹配变量的类型。 auto x{123}; 中
std::initializer_list 中只有 一个元素,这并不是我们想要的结果。C++17将会生成一个对应的整型值。
经验法则:

  • auto var_name {one_element}; 将会推导出var_name的类型——与one_element一样。
  • auto var_name {element1, element2, …}; 是非法的,并且无法通过编译。
  • auto var_name = {element1, element2, …}; 将会使用std::initializer_list 进行初始化,列表中elementN变量的类型均为T。
    C++17加强了初始化列表的鲁棒性。
    注意:

使用C++11/C++14模式的编译器解决这个问题时,有些编译器会将auto x{123}; 的类型推导成整型,而另外一些则会推导成
std::initializer_list 。所以,这里需要特别注意,编写这样的代码,可能会导致有关可移植性的问题!

猜你喜欢

转载自blog.csdn.net/EBDSoftware/article/details/128482811