C++
语言 | Language

Default arguments

默认参数

允许调用函数而不提供一个或多个尾随参数。

参数列表中的参数使用下列语法指示功能声明...

attr(optional) decl-specifier-seq declarator = initializer(1)
attr(optional) decl-specifier-seq abstract-declarator(optional) = initializer(2)

在函数调用中,使用默认参数来代替缺少的尾随参数:

二次

void point(int x = 3, int y = 4 point(1,2 // calls point(1,2) point(1 // calls point(1,4) point( // calls point(3,4)

二次

在函数声明中,在带有默认参数的参数之后,所有后续参数必须。

  • 在本声明或先前声明中提供默认参数;或

  • 是一个函数参数包。%28自C++11%29

省略号不是参数,因此可以使用默认参数跟随参数。

二次

int f(int = 1, int // error, assuming there's no previous declaration of f int g(int n = 0, ... // ok template<class...T> void h(int i = 0, T... args // ok

二次

的参数列表中只允许默认参数。函数声明和Lambda-表达式,自C++14%29以来,不允许在指向函数、函数引用或胡枝子f声明。模板参数列表使用类似的语法默认模板参数...

对于非模板函数,可以将默认参数添加到已声明的函数中,如果该函数在同一范围内重新声明。在函数调用的点,默认值是函数的所有可见声明中提供的默认值的结合。即使该值与%29相同,重声明也不能为默认值已可见%28的参数引入默认值。内部作用域中的重新声明不会从外部范围获取默认参数。

二次

void f(int, int // #1 void f(int, int = 7 // #2 OK: adds a default void h() { f(3 // #1 and #2 are in scope; makes a call to f(3,7) void f(int =1, int // Error: inner scope declarations don't acquire defaults } void m() { // new scope begins void f(int, int // inner scope declaration; has no defaults. f(4 // Error: not enough arguments to call f(int, int) void f(int, int = 6 f(4 // OK: calls f(4,6 void f(int, int = 6 // Error: cannot redeclare a default in the same scope } void f(int = 1, int // #3 OK, adds a default to #2 void n() { // new scope begins f( // #1, #2, and #3 are in scope: calls f(1, 7 }

二次

如果内联函数在不同的翻译单元中声明,在每个翻译单元的末尾,累积的默认参数集必须相同。

如果朋友声明指定一个默认的,它必须是一个朋友函数定义,并且在翻译单元中不允许该函数的其他声明。

大使用-声明继承已知的默认参数集,如果以后向函数%27s命名空间添加更多参数,则在可见使用声明的任何地方也可以看到这些默认值。

二次

namespace N { void f(int, int = 1 } using N::f; void g() { f(7 // calls f(7, 1 f( // error } namespace N { void f(int = 2, int } void h() { f( // calls f(2, 1 }

二次

将查找默认参数中使用的名称,并对其进行检查。可达性,并在声明点绑定,但在函数调用点执行:

二次

int a = 1; int f(int int g(int x = f(a) // lookup for f finds ::f, lookup for a finds ::a // the value of ::a, which is 1 at this point, is not used void h() { a = 2; // changes the value of ::a { int a = 3; g( // calls f(2), then calls g() with the result } }

二次

为了成员函数对于非模板类,默认参数允许在类外定义中使用,并与类主体内的声明提供的默认参数相结合。如果这些类外默认值会将成员函数转换为默认、复制或移动构造函数,则程序的格式不正确。对于类模板的成员函数,必须在成员函数的初始声明中提供所有默认值。

二次

class C { void f(int i = 3 void g(int i, int j = 99 C(int arg // non-default constructor }; void C::f(int i = 3) { // error: default argument already } // specified in class scope void C::g(int i = 88, int j) { // OK: in this translation unit, } // C::g can be called with no argument C::C(int arg = 1) { // Error: turns this into a default constructor }

二次

霸王虚拟函数不会从基类声明中获取默认参数,当进行虚拟函数调用时,根据对象%28注意事项的静态类型确定默认参数:这可以通过非虚拟接口模式%29

二次

struct Base { virtual void f(int a = 7 }; struct Derived : Base { void f(int a) override; }; void m() { Derived d; Base& b = d; b.f( // OK: calls Derived::f(7) d.f( // Error: no default }

二次

默认参数中不允许局部变量,除非在未计算的上下文%28中使用,因为C++14%29:

二次

void f() { int n = 1; extern void g(int x = n // error: local variable cannot be a default extern void h(int x = sizeof n // OK as of CWG 2082 }

二次

大这默认参数中不允许指针:

二次

class A { void f(A* p = this) { } // error: this is not allowed };

二次

默认参数%28不允许非静态类成员,即使它们未被计算为%29,除非用于形成指向成员的指针或在成员访问表达式中。

二次

int b; class X { int a; int mem1(int i = a // error: non-static member cannot be used int mem2(int i = b // OK: lookup finds X::b, the static member static int b; };

二次

函数参数在默认参数%28中是不允许的,即使它们在C++14%29之前未被计算为%29%28,除非它们是自C++14%29以来未计算的%28。注意,参数列表前面出现的参数位于范围*

二次

int a; int f(int a, int b = a // Error: the parameter a used in a default argument int g(int a, int b = sizeof a // Error until CWG 2082 // OK after CWG 2082: use in unevaluated context is OK

二次

默认参数不是函数类型的一部分。

二次

int f(int = 0 void h() { int j = f(1 int k = f( // calls f(0 } int (*p1)(int) = &f; int (*p2)() = &f; //Error: the type of f is int(int)

二次

如果Lambda表达出现在默认参数中,它不能显式或隐式地捕获任何内容。

二次

void f2() { int i = 1; void g1(int = ([i]{ return i; })() // error: captures something void g2(int = ([i]{ return 0; })() // error: captures something void g3(int = ([=]{ return i; })() // error: captures something void g4(int = ([=]{ return 0; })() // OK: capture-less void g5(int = ([]{ return sizeof i; })() // OK: capture-less }

二次

运算符函数除函数调用操作符外,不应有默认参数。

二次

class C { int operator[](int i = 0 // ill-formed int operator()(int x = 0 // ok };

二次

缺陷报告

以下行为更改缺陷报告追溯应用于先前发布的C++标准。

DRApplied toBehavior as publishedCorrect behavior
CWG 2082C++14default arguments were forbidden to use locals in unevaluated contextunevaluated context use allowed

© cppreference.com

在CreativeCommonsAttribution下授权-ShareAlike未移植许可v3.0。

http://en.cppreference.com/w/cpp/language/default[医]论点