Overloading and const Parameters
重载和 const 形参
Whether a parameter is const only matters when the parameter is a reference or pointer. 仅当形参是引用或指针时,形参是否为const 才有影响。 |
We can overload a function based on whether a reference parameter refers to aconst or nonconst type. Overloading on const for a reference parameter is valid because the compiler can use whether the argument isconst to determine which function to call:
可基于函数的引用形参是指向 const 对象还是指向非 const 对象,实现函数重载。将引用形参定义为const 来重载函数是合法的,因为编译器可以根据实参是否为 const 确定调用哪一个函数:
Record lookup(Account&); Record lookup(const Account&); // new function const Account a(0); Account b; lookup(a); // calls lookup(const Account&) lookup(b); // calls lookup(Account&)
If the parameter is a plain reference, then we may not pass a const object for that parameter. If we pass a const object, then the only function that is viable is the version that takes aconst reference.
如果形参是普通的引用,则不能将 const 对象传递给这个形参。如果传递了 const 对象,则只有带const 引用形参的版本才是该调用的可行函数。
When we pass a nonconst object, either function is viable. We can use a nonconst object to initializer either aconst or nonconst reference. However, initializing a const reference to a nonconst object requires a conversion, whereas initializing a nonconst parameter is an exact match.
如果传递的是非 const 对象,则上述任意一种函数皆可行。非 const 对象既可用于初始化const 引用,也可用于初始化非 const 引用。但是,将 const 引用初始化为非 const 对象,需通过转换来实现,而非const 形参的初始化则是精确匹配。
Pointer parameters work in a similar way. We may pass the address of aconst object only to a function that takes a pointer to const. We may pass a pointer to a nonconst object to a function taking a pointer to aconst or nonconst type. If two functions differ only as to whether a pointer parameter points toconst or nonconst, then the parameter that points to the nonconst type is a better match for a pointer to a nonconst object. Again, the compiler can distinguish: If the argument isconst, it calls the function that takes a const*; otherwise, if the argument is a nonconst, the function taking a plain pointer is called.
对指针形参的相关处理如出一辙。可将 const 对象的地址值只传递给带有指向 const 对象的指针形参的函数。也可将指向非const 对象的指针传递给函数的 const 或非 const 类型的指针形参。如果两个函数仅在指针形参时是否指向const 对象上不同,则指向非 const 对象的指针形参对于指向非 const 对象的指针(实参)来说是更佳的匹配。重复强调,编译器可以判断:如果实参是const 对象,则调用带有 const* 类型形参的函数;否则,如果实参不是 const 对象,将调用带有普通指针形参的函数。
It is worth noting that we cannot overload based on whether the pointer itself isconst:
注意不能基于指针本身是否为 const 来实现函数的重载:
f(int *);
f(int *const); // redeclaration
Here the const applies to the pointer, not the type to which the pointer points. In both cases the pointer is copied; it makes no difference whether the pointer itself isconst. As we noted on page 267, when a parameter is passed as a copy, we cannot overload based on whether that parameter isconst.
此时,const 用于修改指针本身,而不是修饰指针所指向的类型。在上述两种情况中,都复制了指针,指针本身是否为const 并没有带来区别。正如前面第 7.8 节所提到的,当形参以副本传递时,不能基于形参是否为const 来实现重载。
例如:
(a) int calc(char*, char*); int calc(const char*, const char*); (b) int calc(char*, char*); int calc(char* const, char* const);
(a)中第二个声明的效果是,声明了一个重载的calc函数
(b)中第二个声明的效果是对第一个声明的重复声明,因为当形参以副本传递(即按值传值)时,不能基于形参是否是const来实现重载。