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

标签 c++ c++11 optional-parameters default-constructor

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

void foo(a::really::long::type::name arg = a::really::long::type::name());

有没有更好的语法不涉及两次输入类型名称?比如:

void foo(a::really::long::type::name arg = default);

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

最佳答案

是的:

void foo(a::really::long::type::name arg = {});

总结以下标准定义:

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

当类型是 std::initializer_list 的特化或类型具有 std::initializer_list 构造函数(如果它没有默认构造函数)


相关的标准引用(按照我们遇到的定义):

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

1 If an initializer-clause is specified in a parameter-declaration this initializer-clause is used as a default argument

5 The default argument has the same semantic constraints as the initializer in a declaration of a variable of the parameter type, using the copy-initialization semantics (8.5)

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

1 List-initialization is initialization of an object or reference from a braced-init-list. Such an initializer is called an initializer list, [...]. An initializer list may be empty. List-initialization can occur in direct-initialization or copy initialization contexts; [..] list-initialization in a copy-initialization context is called copy-list-initialization.

3 List-initialization of an object or reference of type T is defined as follows:

  • If T is an aggregate, aggregate initialization is performed (8.5.1)
  • Otherwise, if the initializer list has no elements and T is a class type with a default constructor, the object is value-initialized.
  • Otherwise, if T is a specialization of std::initializer_list, a prvalue initializer_list object is constructed as described below and used to initialize the object according to the rules for initialization of an object from a class of the same type (8.5).
  • Otherwise, if T is a class type, constructors are considered. The applicable constructors are enumerated and the best one is chosen through overload resolution (13.3, 13.3.1.7) [...]
  • ...
  • Otherwise, if the initializer list has no elements, the object is value-initialized.

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

8 To value-initialize an object of type T means:

  • if T is a (possibly cv-qualified) class type (Clause 9) with either no default constructor (12.1) or a default constructor that is user-provided or deleted, then the object is default-initialized;
  • if T is a (possibly cv-qualified) class type without a user-provided or deleted default constructor, then the object is zero-initialized and the semantic constraints for default-initialization are checked, and if T has a non-trivial default constructor, the object is default-initialized;
  • if T is an array type, then each element is value-initialized;
  • otherwise, the object is zero-initialized

7 To default-initialize an object of type T means:

  • if T is a (possibly cv-qualified) class type (Clause 9), the default constructor (12.1) for T is called (and the initialization is ill-formed if T has no default constructor or overload resolution (13.3) results in an ambiguity or in a function that is deleted or inaccessible from the context of the initialization);
  • if T is an array type, each element is default-initialized;
  • otherwise, no initialization is performed.

6 To zero-initialize an object or reference of type T means:

  • if T is a scalar type (3.9), the object is initialized to the value obtained by converting the integer literal 0 (zero) to T;
  • if T is a (possibly cv-qualified) non-union class type, each non-static data member and each base-class subobject is zero-initialized and padding is initialized to zero bits;
  • if T is a (possibly cv-qualified) union type, the object’s first non-static named data member is zero-initialized and padding is initialized to zero bits;
  • if T is an array type, each element is zero-initialized;
  • if T is a reference type, no initialization is performed.

§13.3.1.7 通过列表初始化 [over.match.list] 进行初始化

1 When objects of non-aggregate class type T are list-initialized (8.5.4), overload resolution selects the constructor in two phases:

  • Initially, the candidate functions are the initializer-list constructors (8.5.4) of the class T and the argument list consists of the initializer list as a single argument.
  • If no viable initializer-list constructor is found, overload resolution is performed again, where the candidate functions are all the constructors of the class T and the argument list consists of the elements of the initializer list.

If the initializer list has no elements and T has a default constructor, the first phase is omitted. [...]

关于c++ - 将默认参数值设置为默认构造函数的更好语法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38131945/

相关文章:

html - 同一台 Linux PC 上的网站和 C++ 程序之间的通信

c++ - 将函数分离到 C 中的另一个源文件时出错

c++ - 如何根据模板类的基类专门化成员函数

c++ - 当存在修饰符(L、u8 等)时,相邻字符串文字连接会发生什么情况?

php - 有什么方法可以在 PHP 中指定可选参数值?

c++ - 使用少于需要的参数调用函数

c++ - 从 istream 读取输入直到 EOF

c++ - SDL/C++ 包含问题

c++ - 使用 High_resolution_clock 的时间测量未按预期工作

C# - 如何跳过具有默认值的参数?