具有 const 参数的友元函数
friend functions with const parameters
我知道要创建一个友元函数,友元函数应该在封闭范围内显式声明或采用其 class 的参数。但是,这似乎是一个警告,我无法理解。为什么对 f1(99)
的调用不起作用?
class X {
public:
X(int i) {
std::cout << "Ctor called" << std::endl;
}
friend int f1(X&);
friend int f2(const X&);
friend int f3(X);
};
int f1(X& a) {
std::cout << "non-const called" << std::endl;
}
int f2(const X& a) {
std::cout << "const called" << std::endl;
}
int f3(X a) {
std::cout << "object called" << std::endl;
}
int main() {
f1(99);
f2(99);
f3(99);
}
您正在使用参数 99
调用函数;但所有功能都需要 X
。 99
可以隐式转换为 X
,但转换后的 X
是一个临时对象,不能绑定到非常量的左值引用。
临时对象可以绑定到 lvalue-reference to const(自 C++11 起也是右值引用),然后 f2(99);
就可以工作了。并且它可以被复制到f3
的参数中,那么f3(99)
也可以。
The effects of reference initialization are:
Otherwise, if the reference is lvalue reference to a non-volatile const-qualified type or rvalue reference (since C++11)
:
- Otherwise, object is implicitly converted to T. The reference is bound to the result of the conversion
(after materializing a temporary) (since C++17)
. If the object (or, if the conversion is
done by user-defined conversion, the result of the conversion
function) is of type T or derived from T, it must be equally or less
cv-qualified than T, and, if the reference is an rvalue reference, must not be an lvalue (since C++11)
.
我知道要创建一个友元函数,友元函数应该在封闭范围内显式声明或采用其 class 的参数。但是,这似乎是一个警告,我无法理解。为什么对 f1(99)
的调用不起作用?
class X {
public:
X(int i) {
std::cout << "Ctor called" << std::endl;
}
friend int f1(X&);
friend int f2(const X&);
friend int f3(X);
};
int f1(X& a) {
std::cout << "non-const called" << std::endl;
}
int f2(const X& a) {
std::cout << "const called" << std::endl;
}
int f3(X a) {
std::cout << "object called" << std::endl;
}
int main() {
f1(99);
f2(99);
f3(99);
}
您正在使用参数 99
调用函数;但所有功能都需要 X
。 99
可以隐式转换为 X
,但转换后的 X
是一个临时对象,不能绑定到非常量的左值引用。
临时对象可以绑定到 lvalue-reference to const(自 C++11 起也是右值引用),然后 f2(99);
就可以工作了。并且它可以被复制到f3
的参数中,那么f3(99)
也可以。
The effects of reference initialization are:
Otherwise, if the reference is lvalue reference to a non-volatile const-qualified type
or rvalue reference (since C++11)
:
- Otherwise, object is implicitly converted to T. The reference is bound to the result of the conversion
(after materializing a temporary) (since C++17)
. If the object (or, if the conversion is done by user-defined conversion, the result of the conversion function) is of type T or derived from T, it must be equally or less cv-qualified than T, and, if the reference is an rvalue reference, must not be an lvalue (since C++11)
.