简体   繁体   中英

Function takes a reference parameter with a default value

Based on http://www.cplusplus.com/reference/stl/vector/vector/

explicit vector ( const Allocator& = Allocator() );

This vector constructor takes a reference parameter which has default value of Allocator(). What I learn from this function signature is that a function can take a reference parameter with default value.

This the demo code I play with VS2010.

#include "stdafx.h"
#include <iostream>

using namespace std;

void funA(const int& iValue=5) // reference to a template const int 5 why?
{
    cout << iValue << endl;
}

int _tmain(int argc, _TCHAR* argv[])
{
    funA();
    funA(10);
    return 0;
}

are there some rules to guide this syntax usage (ie a reference parameter with a default value)?

Const引用可以绑定到临时对象,在这种情况下,临时对象的生命周期延伸到引用的生命周期。

This behavior is defined in § 8.3.6 5 of c++03:

A default argument expression is implicitly converted ( clause 4 ) to the parameter type. The default argument expression has the same semantic constraints as the initializer expression in a declaration of a variable of the parameter type, using the copy-initialization semantics ( 8.5 ).

That is, const Type& var = val is a valid parameter declaration only if it's also a valid variable declaration. According to § 8.5.3 5, it is. For const Allocator& = Allocator() , the following applies:

  • Otherwise, the reference shall be to a non-volatile const type (ie, cv1 shall be const). [...]
    • If the initializer expression is an rvalue, with a class type, and " cv1 " is reference-compatible with " cv2 ," the reference is bound in one of the following ways (the choice is implementation defined): 是类类型,并且“ cv1 ”与“ cv2 ”引用兼容,则引用将以下列方式之一绑定(选择是实现定义):

      • The reference is bound to the object represented by the rvalue (see 3.10 ) or to a sub-object within that object.
      • A temporary of type " cv2 " [sic] is created, and a constructor is called to copy the entire rvalue object into the temporary. ”[sic],并调用构造函数将整个rvalue对象复制到临时对象中。 The reference is bound to the temporary or to a sub-object within the temporary.

      The constructor that would be used to make the copy shall be callable whether or not the copy is actually done. [...]

    • Otherwise, [...]

For const int& iValue=5 , the next case applies:

  • Otherwise, the reference shall be to a non-volatile const type (ie, cv1 shall be const). [...]
    • If the initializer expression is an rvalue[...]

    • Otherwise, a temporary of type " cv1 " is created and initialized from the initializer expression using the rules for a non-reference copy initialization ( 8.5 ). ”的临时类型。 The reference is then bound to the temporary. If is reference-related to , cv1 must be the same cv-qualification as, or greater cv-qualification than, cv2 ; 有参考关系,则cv1必须与cv- qualified相同,或者cv-qualification与cv2相同 ; otherwise, the program is ill-formed. [Example:

      \n          const double& rcd2 = 2;  // rcd2 refers to temporary with value 2.0 \n          const volatile int cvi = 1; \n          const int& r = cvi;  // error: type qualifiers dropped \n
      ---end example]

In short, a real, though perhaps temporary, variable is created so the reference can refer to it. It's allowed in parameter declarations exactly so that reference parameters can take default values. Otherwise, it would be a needless restriction. The more orthogonal a language is, the easier it is to keep in your head, as you don't need to remember as many exceptions to the rules (though, arguably, allowing const references but not non-const references to be bound to rvalues is less orthogonal than disallowing any reference to be bound to an rvalue).

The only rules I can think of are (a) that the reference must be const, because you can't bind a non-const reference to a temporary, and (b) that it's generally better not to use const references to pass built-in types. In other words:

(a)

void f(T& t = T(23)) {} // bad

void g(const T& t = T(23)) {} // fine

(b)

void f(const int& i = 23) {} // sort of ok

void g(int i = 23) {} // better

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM