将默认参数值设置为默认构造函数的更好语法

Typ*_*eIA 38 c++ optional-parameters default-constructor c++11

有人可能想要使用参数声明一个函数,并指定参数的默认值是类型的默认构造函数的结果:

void foo(a::really::long::type::name arg = a::really::long::type::name());
Run Code Online (Sandbox Code Playgroud)

是否有更好的语法,不涉及输入类型名称两次?就像是:

void foo(a::really::long::type::name arg = default);
Run Code Online (Sandbox Code Playgroud)

我意识到我可以typedef使用类型名称使其更漂亮,但我很好奇是否存在这样的语法.

bol*_*lov 56

是:

void foo(a::really::long::type::name arg = {});
Run Code Online (Sandbox Code Playgroud)

总结以下标准定义:

这是列表初始化.根据类型,执行聚合初始化或对象初始化值,这反过来意味着默认初始化或零初始化.

一些"角落"情况是当类型是特化std::initializer_list或类型具有std::initializer_list构造函数时(如果它没有默认构造函数则调用它)


相关的标准报价(按顺序我们会遇到定义):

§8.3.6默认参数[dcl.fct.default]

1如果在参数声明中指定了initializer子句,则此初始化子句用作默认参数

5使用复制初始化语义(8.5),默认参数与参数类型变量声明中的初始化程序具有相同的语义约束

§8.5.4列表初始化[dcl.init.list]

1列表初始化是从braced-init-list初始化对象或引用.这样的初始化程序称为初始化程序列表,[...].初始化列表可以为空.列表初始化可以在直接初始化或复制初始化上下文中进行; [...]复制初始化上下文中的列表初始化称为复制列表初始化.

3类型T的对象或引用的列表初始化定义如下:

  • 如果T是聚合,则执行聚合初始化(8.5.1)
  • 否则,如果初始化程序列表没有元素且T是具有默认构造函数的类类型,则对象将进行值初始化.
  • 否则,如果T是std :: initializer_list的特化,则如下所述构造prvalue initializer_list对象,并用于根据相同类型的类(8.5)中的对象初始化规则初始化对象.
  • 否则,如果T是类类型,则考虑构造函数.列举了适用的构造函数,并通过重载决策选择最佳构造函数(13.3,13.3.1.7)[...]
  • ...
  • 否则,如果初始化列表没有元素,则对象进行值初始化.

§8.5初始化程序[dcl.init]

8要初始化 T类型的对象,意味着:

  • 如果T是一个(可能是cv限定的)类类型(第9条),没有默认构造函数(12.1)或者是用户提供或删除的默认构造函数,那么该对象是默认初始化的 ;
  • 如果T是一个(可能是cv限定的)类类型而没有用户提供或删除的默认构造函数,那么该对象是零初始化 的,并且检查默认初始化的语义约束,如果T有一个非平凡的默认构造函数,该对象是 默认初始化的 ;
  • 如果T是数组类型,那么每个元素都是值初始化的 ;
  • 否则,该对象被零初始化

7 默认初始化 T类型的对象意味着:

  • 如果T是(可能是cv限定的)类类型(第9节),则调用T的默认构造函数(12.1)(如果T没有默认构造函数或重载解析(13.3),则初始化是错误的模糊性或在初始化上下文中删除或无法访问的函数中;
  • 如果T是数组类型,则每个元素都是默认初始化的 ;
  • 否则,不执行初始化.

6 零初始化 T类型的对象或引用意味着:

  • 如果T是标量类型(3.9),则将对象初始化为通过将整数0(零)转换为T而获得的值;
  • 如果T是(可能是cv限定的)非联合类类型,则每个非静态数据成员和每个基类子对象都是零初始化的,并且填充初始化为零位;
  • 如果T是(可能是cv限定的)联合类型,则对象的第一个非静态命名数据成员被零初始化,并且填充被初始化为零位;
  • 如果T是数组类型,则每个元素都是零初始化的;
  • 如果T是引用类型,则不执行初始化.

§13.3.1.7按列表初始化初始化[over.match.list]

1当非聚合类类型T的对象被列表初始化(8.5.4)时,重载决策分两个阶段选择构造函数:

  • 最初,候选函数是类T 的初始化列表构造函数(8.5.4),参数列表由初始化列表作为单个参数组成.
  • 如果找不到可行的初始化列表构造函数,则再次执行重载解析,其中候选函数是类T的所有构造函数,参数列表由初始化列表的元素组成.

如果初始化列表没有元素且T具有默认构造函数,则省略第一个阶段.[...]

  • 它不是很有价值的初始化. (2认同)