请参阅下面的代码。 drive()
在范围内,我可以drive
porsche
。但是,除非我取消注释drive()
的声明,否则g ++会在尝试创建仿函数时在此范围错误中声明一个非常奇怪的“驱动器”。为什么呢?
#include <functional>
class car {
friend void drive(const car c);
};
//void drive(const car c);
int main() {
car porsche;
drive(porsche);
std::pointer_to_unary_function<car, void> functor(drive);
return 0;
}
更新1:我对ADL的答案几乎感到满意,但是我确实告诉了驱动器参数的类型,它是第一个模板参数,它是汽车:
std::pointer_to_unary_function<car, void> functor(drive);
更新2:好的,这是一个更简单的代码,我们不需要仿函数和函数头:
class car {
friend void drive(const car c);
};
//void drive(const car c) { }
int main() {
car porsche;
drive(porsche);
void (*f)(const car);
f = drive;
return 0;
}
现在,我理解为什么编译器无法使用ADL找到drive
。原因与上面相同,但模板不会掩盖此代码。
答案 0 :(得分:5)
当您在类中声明一个具有非限定id的friend
函数并且该函数不是另一个类的成员时,它会在最近的封闭非类非函数原型范围中命名一个函数。 / p>
如果先前未声明该函数,则friend
声明不会使该函数在该范围内可见。
但是,该函数对参数相关的查找是可见的。
在表达式drive(porsche);
中,porsche
的类型为car
,因此可以使用ADL并找到友元函数。
在表达式drive
中没有参数,因此不执行ADL。没有drive
的声明可见,因此查找失败。
答案 1 :(得分:0)
因为朋友没有声明一个函数,而你正试图调用一个不存在的全局函数。